/**
 * MaNGOS is a full featured server for World of Warcraft, supporting
 * the following clients: 1.12.x, 2.4.3, 3.3.5a, 4.3.4a and 5.4.8
 *
 * Copyright (C) 2005-2021 MaNGOS <https://getmangos.eu>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * World of Warcraft, and all World of Warcraft or Warcraft art, images,
 * and lore are copyrighted by Blizzard Entertainment, Inc.
 */

/**
 * \addtogroup game
 * @{
 * \file
 */
#ifndef MANGOS_H_UNIT
#define MANGOS_H_UNIT

#include "Common.h"
#include "Object.h"
#include "Opcodes.h"
#include "SpellAuraDefines.h"
#include "UpdateFields.h"
#include "SharedDefines.h"
#include "ThreatManager.h"
#include "HostileRefManager.h"
#include "FollowerReference.h"
#include "FollowerRefManager.h"
#include "Utilities/EventProcessor.h"
#include "MotionMaster.h"
#include "DBCStructure.h"
#include "WorldPacket.h"
#include "Timer.h"
#include "Log.h"

#include <list>

enum SpellInterruptFlags
{
    SPELL_INTERRUPT_FLAG_MOVEMENT     = 0x01,
    SPELL_INTERRUPT_FLAG_DAMAGE       = 0x02,
    SPELL_INTERRUPT_FLAG_INTERRUPT    = 0x04,
    SPELL_INTERRUPT_FLAG_AUTOATTACK   = 0x08,
    SPELL_INTERRUPT_FLAG_ABORT_ON_DMG = 0x10               // _complete_ interrupt on direct damage
    // SPELL_INTERRUPT_UNK               = 0x20               // unk, 564 of 727 spells having this spell start with "Glyph"
};

enum SpellChannelInterruptFlags
{
    CHANNEL_FLAG_DAMAGE      = 0x0002,
    CHANNEL_FLAG_MOVEMENT    = 0x0008,
    CHANNEL_FLAG_TURNING     = 0x0010,
    CHANNEL_FLAG_DAMAGE2     = 0x0080,
    CHANNEL_FLAG_DELAY       = 0x4000
};

enum SpellAuraInterruptFlags
{
    AURA_INTERRUPT_FLAG_UNK0                        = 0x00000001,   // 0    removed when getting hit by a negative spell?
    AURA_INTERRUPT_FLAG_DAMAGE                      = 0x00000002,   // 1    removed by any damage
    AURA_INTERRUPT_FLAG_UNK2                        = 0x00000004,   // 2
    AURA_INTERRUPT_FLAG_MOVE                        = 0x00000008,   // 3    removed by any movement
    AURA_INTERRUPT_FLAG_TURNING                     = 0x00000010,   // 4    removed by any turning
    AURA_INTERRUPT_FLAG_ENTER_COMBAT                = 0x00000020,   // 5    removed by entering combat
    AURA_INTERRUPT_FLAG_NOT_MOUNTED                 = 0x00000040,   // 6    removed by unmounting
    AURA_INTERRUPT_FLAG_NOT_ABOVEWATER              = 0x00000080,   // 7    removed by entering water
    AURA_INTERRUPT_FLAG_NOT_UNDERWATER              = 0x00000100,   // 8    removed by leaving water
    AURA_INTERRUPT_FLAG_NOT_SHEATHED                = 0x00000200,   // 9    removed by unsheathing
    AURA_INTERRUPT_FLAG_UNK10                       = 0x00000400,   // 10
    AURA_INTERRUPT_FLAG_UNK11                       = 0x00000800,   // 11
    AURA_INTERRUPT_FLAG_MELEE_ATTACK                = 0x00001000,   // 12   removed by melee attacks
    AURA_INTERRUPT_FLAG_UNK13                       = 0x00002000,   // 13
    AURA_INTERRUPT_FLAG_UNK14                       = 0x00004000,   // 14
    AURA_INTERRUPT_FLAG_UNK15                       = 0x00008000,   // 15   removed by casting a spell?
    AURA_INTERRUPT_FLAG_UNK16                       = 0x00010000,   // 16
    AURA_INTERRUPT_FLAG_MOUNTING                    = 0x00020000,   // 17   removed by mounting
    AURA_INTERRUPT_FLAG_NOT_SEATED                  = 0x00040000,   // 18   removed by standing up (used by food and drink mostly and sleep/Fake Death like)
    AURA_INTERRUPT_FLAG_CHANGE_MAP                  = 0x00080000,   // 19   leaving map/getting teleported
    AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION    = 0x00100000,   // 20   removed by auras that make you invulnerable, or make other to loose selection on you
    AURA_INTERRUPT_FLAG_UNK21                       = 0x00200000,   // 21
    AURA_INTERRUPT_FLAG_UNK22                       = 0x00400000,   // 22
    AURA_INTERRUPT_FLAG_ENTER_PVP_COMBAT            = 0x00800000,   // 23   removed by entering pvp combat
    AURA_INTERRUPT_FLAG_DIRECT_DAMAGE               = 0x01000000    // 24   removed by any direct damage
};

enum SpellModOp
{
    SPELLMOD_DAMAGE                 = 0,
    SPELLMOD_DURATION               = 1,
    SPELLMOD_THREAT                 = 2,
    SPELLMOD_ATTACK_POWER           = 3,
    SPELLMOD_CHARGES                = 4,
    SPELLMOD_RANGE                  = 5,
    SPELLMOD_RADIUS                 = 6,
    SPELLMOD_CRITICAL_CHANCE        = 7,
    SPELLMOD_ALL_EFFECTS            = 8,
    SPELLMOD_NOT_LOSE_CASTING_TIME  = 9,
    SPELLMOD_CASTING_TIME           = 10,
    SPELLMOD_COOLDOWN               = 11,
    SPELLMOD_SPEED                  = 12,
    // spellmod 13 unused
    SPELLMOD_COST                   = 14,
    SPELLMOD_CRIT_DAMAGE_BONUS      = 15,
    SPELLMOD_RESIST_MISS_CHANCE     = 16,
    SPELLMOD_JUMP_TARGETS           = 17,
    SPELLMOD_CHANCE_OF_SUCCESS      = 18,                   // Only used with SPELL_AURA_ADD_FLAT_MODIFIER and affects proc spells
    SPELLMOD_ACTIVATION_TIME        = 19,
    SPELLMOD_EFFECT_PAST_FIRST      = 20,
    SPELLMOD_CASTING_TIME_OLD       = 21,
    SPELLMOD_DOT                    = 22,
    SPELLMOD_HASTE                  = 23,
    SPELLMOD_SPELL_BONUS_DAMAGE     = 24,
    // spellmod 25 unused
    // SPELLMOD_FREQUENCY_OF_SUCCESS   = 26,
    SPELLMOD_MULTIPLE_VALUE         = 27,
    SPELLMOD_RESIST_DISPEL_CHANCE   = 28
};

#define MAX_SPELLMOD 32

enum SpellFacingFlags
{
    SPELL_FACING_FLAG_INFRONT = 0x0001
};

#define BASE_MELEERANGE_OFFSET 1.33f
#define BASE_MINDAMAGE 1.0f
#define BASE_MAXDAMAGE 2.0f
#define BASE_ATTACK_TIME 2000

/**
 * byte value (UNIT_FIELD_BYTES_1,0).
 *
 * This is not to be used as a bitmask but as one value
 * each, ie: you can't be standing and sitting down at
 * the same time.
 * \see Unit::getStandState
 * \see Unit::SetStandState
 * \see Unit::IsSitState
 * \see Unit::IsStandState
 */
enum UnitStandStateType
{
    UNIT_STAND_STATE_STAND             = 0,
    UNIT_STAND_STATE_SIT               = 1,
    UNIT_STAND_STATE_SIT_CHAIR         = 2,
    UNIT_STAND_STATE_SLEEP             = 3,
    UNIT_STAND_STATE_SIT_LOW_CHAIR     = 4,
    UNIT_STAND_STATE_SIT_MEDIUM_CHAIR  = 5,
    UNIT_STAND_STATE_SIT_HIGH_CHAIR    = 6,
    UNIT_STAND_STATE_DEAD              = 7,
    UNIT_STAND_STATE_KNEEL             = 8,
};

#define MAX_UNIT_STAND_STATE             9

/* byte flag value not exist in 1.12, moved/merged in (UNIT_FIELD_BYTES_1,3), in post-1.x it's in (UNIT_FIELD_BYTES_1,2)
enum UnitStandFlags
*/

// byte flags value (UNIT_FIELD_BYTES_1,2)
// This corresponds to free talent points (pet case)

// byte flags value (UNIT_FIELD_BYTES_1,3)
enum UnitBytes1_Flags
{
    UNIT_BYTE1_FLAG_ALWAYS_STAND = 0x01,
    UNIT_BYTE1_FLAGS_CREEP       = 0x02,
    UNIT_BYTE1_FLAG_UNTRACKABLE  = 0x04,
    UNIT_BYTE1_FLAG_ALL          = 0xFF
};

/**
 *  byte value (UNIT_FIELD_BYTES_2,0)
 */
enum SheathState
{
    /// non prepared weapon
    SHEATH_STATE_UNARMED  = 0,
    /// prepared melee weapon
    SHEATH_STATE_MELEE    = 1,
    /// prepared ranged weapon
    SHEATH_STATE_RANGED   = 2
};

#define MAX_SHEATH_STATE    3

// byte flags value (UNIT_FIELD_BYTES_2,1)
enum UnitBytes2_Flags
{
    UNIT_BYTE2_FLAG_UNK0        = 0x01,
    UNIT_BYTE2_FLAG_UNK1        = 0x02,
    UNIT_BYTE2_FLAG_UNK2        = 0x04,
    UNIT_BYTE2_FLAG_UNK3        = 0x08,
    UNIT_BYTE2_FLAG_AURAS       = 0x10,                     // show positive auras as positive, and allow its dispel
    UNIT_BYTE2_FLAG_UNK5        = 0x20,
    UNIT_BYTE2_FLAG_UNK6        = 0x40,
    UNIT_BYTE2_FLAG_UNK7        = 0x80
};

#define CREATURE_MAX_SPELLS     4

enum Swing
{
    NOSWING                    = 0,
    SINGLEHANDEDSWING          = 1,
    TWOHANDEDSWING             = 2
};

/**
 * This seems to be the state a target of an attack can be in.
 * \todo Document more
 */
enum VictimState
{
    VICTIMSTATE_UNAFFECTED     = 0,                         // seen in relation with HITINFO_MISS
    VICTIMSTATE_NORMAL         = 1,
    VICTIMSTATE_DODGE          = 2,
    VICTIMSTATE_PARRY          = 3,
    VICTIMSTATE_INTERRUPT      = 4,
    VICTIMSTATE_BLOCKS         = 5,
    VICTIMSTATE_EVADES         = 6,
    VICTIMSTATE_IS_IMMUNE      = 7,
    VICTIMSTATE_DEFLECTS       = 8
};

/**
 * OFFSWING and BASESWING/2 or MAINSWING/2 to be more
 * in line with what is used in the other parts?
 *
 * \todo Rename the LEFTSWING and NORMALSWING/2 to:
 */
enum HitInfo
{
    HITINFO_NORMALSWING         = 0x00000000,
    HITINFO_UNK0                = 0x00000001,               // req correct packet structure
    HITINFO_NORMALSWING2        = 0x00000002,
    HITINFO_LEFTSWING           = 0x00000004,
    HITINFO_UNK3                = 0x00000008,
    HITINFO_MISS                = 0x00000010,
    HITINFO_ABSORB              = 0x00000020,               // plays absorb sound
    HITINFO_RESIST              = 0x00000040,               // resisted atleast some damage
    HITINFO_CRITICALHIT         = 0x00000080,
    HITINFO_UNK8                = 0x00000100,               // wotlk?
    HITINFO_BLOCK               = 0x00000800,               // [ZERO]
    HITINFO_UNK9                = 0x00002000,               // wotlk?
    HITINFO_GLANCING            = 0x00004000,
    HITINFO_CRUSHING            = 0x00008000,
    HITINFO_NOACTION            = 0x00010000,
    HITINFO_SWINGNOHITSOUND     = 0x00080000
};

// i would like to remove this: (it is defined in item.h
enum InventorySlot
{
    NULL_BAG                   = 0,
    NULL_SLOT                  = 255
};

struct FactionTemplateEntry;
struct Modifier;
struct SpellEntry;
struct SpellEntryExt;

class Aura;
class SpellAuraHolder;
class Creature;
class Spell;
class DynamicObject;
class GameObject;
class Item;
class Pet;
class PetAura;
class Totem;

struct SpellImmune
{
    uint32 type;
    uint32 spellId;
};

typedef std::list<SpellImmune> SpellImmuneList;

enum UnitModifierType
{
    BASE_VALUE = 0,
    BASE_PCT = 1,
    TOTAL_VALUE = 2,
    TOTAL_PCT = 3,
    MODIFIER_TYPE_END = 4
};

enum WeaponDamageRange
{
    MINDAMAGE,
    MAXDAMAGE
};

enum DamageTypeToSchool
{
    RESISTANCE,
    DAMAGE_DEALT,
    DAMAGE_TAKEN
};

/**
 * This is what decides how an \ref Aura was removed, the cause of it being removed.
 */
enum AuraRemoveMode
{
    AURA_REMOVE_BY_DEFAULT,
    AURA_REMOVE_BY_STACK,           ///< at replace by similar aura
    AURA_REMOVE_BY_CANCEL,          ///< It was cancelled by the user (needs confirmation)
    AURA_REMOVE_BY_DISPEL,          ///< It was dispelled by ie Remove Magic
    AURA_REMOVE_BY_DEATH,           ///< The \ref Unit died and there for it was removed
    AURA_REMOVE_BY_DELETE,          ///< use for speedup and prevent unexpected effects at player logout/pet unsummon (must be used _only_ after save), delete.
    AURA_REMOVE_BY_SHIELD_BREAK,    ///< when absorb shield is removed by damage
    AURA_REMOVE_BY_EXPIRE,          ///< at duration end
    AURA_REMOVE_BY_TRACKING         ///< aura is removed because of a conflicting tracked aura
};

enum UnitMods
{
    UNIT_MOD_STAT_STRENGTH,                                 // UNIT_MOD_STAT_STRENGTH..UNIT_MOD_STAT_SPIRIT must be in existing order, it's accessed by index values of Stats enum.
    UNIT_MOD_STAT_AGILITY,
    UNIT_MOD_STAT_STAMINA,
    UNIT_MOD_STAT_INTELLECT,
    UNIT_MOD_STAT_SPIRIT,
    UNIT_MOD_HEALTH,
    UNIT_MOD_MANA,                                          // UNIT_MOD_MANA..UNIT_MOD_HAPPINESS must be in existing order, it's accessed by index values of Powers enum.
    UNIT_MOD_RAGE,
    UNIT_MOD_FOCUS,
    UNIT_MOD_ENERGY,
    UNIT_MOD_HAPPINESS,
    UNIT_MOD_ARMOR,                                         // UNIT_MOD_ARMOR..UNIT_MOD_RESISTANCE_ARCANE must be in existing order, it's accessed by index values of SpellSchools enum.
    UNIT_MOD_RESISTANCE_HOLY,
    UNIT_MOD_RESISTANCE_FIRE,
    UNIT_MOD_RESISTANCE_NATURE,
    UNIT_MOD_RESISTANCE_FROST,
    UNIT_MOD_RESISTANCE_SHADOW,
    UNIT_MOD_RESISTANCE_ARCANE,
    UNIT_MOD_ATTACK_POWER,
    UNIT_MOD_ATTACK_POWER_RANGED,
    UNIT_MOD_DAMAGE_MAINHAND,
    UNIT_MOD_DAMAGE_OFFHAND,
    UNIT_MOD_DAMAGE_RANGED,
    UNIT_MOD_END,
    // synonyms
    UNIT_MOD_STAT_START = UNIT_MOD_STAT_STRENGTH,
    UNIT_MOD_STAT_END = UNIT_MOD_STAT_SPIRIT + 1,
    UNIT_MOD_RESISTANCE_START = UNIT_MOD_ARMOR,
    UNIT_MOD_RESISTANCE_END = UNIT_MOD_RESISTANCE_ARCANE + 1,
    UNIT_MOD_POWER_START = UNIT_MOD_MANA,
    UNIT_MOD_POWER_END = UNIT_MOD_HAPPINESS + 1
};

enum BaseModGroup
{
    CRIT_PERCENTAGE,
    RANGED_CRIT_PERCENTAGE,
    OFFHAND_CRIT_PERCENTAGE,
    SHIELD_BLOCK_VALUE,
    BASEMOD_END
};

enum BaseModType
{
    FLAT_MOD,
    PCT_MOD,
    MOD_END,
};

enum DeathState
{
    ALIVE          = 0,     ///< show as alive
    JUST_DIED      = 1,     ///< temporary state at die, for creature auto converted to CORPSE, for player at next update call
    CORPSE         = 2,     ///< corpse state, for player this also meaning that player not leave corpse
    DEAD           = 3,     ///< for creature despawned state (corpse despawned), for player CORPSE/DEAD not clear way switches (FIXME), and use m_deathtimer > 0 check for real corpse state
    JUST_ALIVED    = 4      ///< temporary state at resurrection, for creature auto converted to ALIVE, for player at next update call
};

/**
 * internal state flags for some auras and movement generators, other. (Taken from comment)
 */
enum UnitState
{
    // persistent state (applied by aura/etc until expire)
    UNIT_STAT_MELEE_ATTACKING = 0x00000001,                 // unit is melee attacking someone Unit::Attack
    UNIT_STAT_ATTACK_PLAYER   = 0x00000002,                 // unit attack player or player's controlled unit and have contested pvpv timer setup, until timer expire, combat end and etc
    UNIT_STAT_DIED            = 0x00000004,                 // Unit::SetFeignDeath
    UNIT_STAT_STUNNED         = 0x00000008,                 // Aura::HandleAuraModStun
    UNIT_STAT_ROOT            = 0x00000010,                 // Aura::HandleAuraModRoot
    UNIT_STAT_ISOLATED        = 0x00000020,                 // area auras do not affect other players, Aura::HandleAuraModSchoolImmunity
    UNIT_STAT_CONTROLLED      = 0x00000040,                 // Aura::HandleAuraModPossess

    // persistent movement generator state (all time while movement generator applied to unit (independent from top state of movegen)
    UNIT_STAT_TAXI_FLIGHT     = 0x00000080,                 // player is in flight mode (in fact interrupted at far teleport until next map telport landing)
    UNIT_STAT_DISTRACTED      = 0x00000100,                 // DistractedMovementGenerator active

    // persistent movement generator state with non-persistent mirror states for stop support
    // (can be removed temporary by stop command or another movement generator apply)
    // not use _MOVE versions for generic movegen state, it can be removed temporary for unit stop and etc
    UNIT_STAT_CONFUSED        = 0x00000200,                 // ConfusedMovementGenerator active/onstack
    UNIT_STAT_CONFUSED_MOVE   = 0x00000400,
    UNIT_STAT_ROAMING         = 0x00000800,                 // RandomMovementGenerator/PointMovementGenerator/WaypointMovementGenerator active (now always set)
    UNIT_STAT_ROAMING_MOVE    = 0x00001000,
    UNIT_STAT_CHASE           = 0x00002000,                 // ChaseMovementGenerator active
    UNIT_STAT_CHASE_MOVE      = 0x00004000,
    UNIT_STAT_FOLLOW          = 0x00008000,                 // FollowMovementGenerator active
    UNIT_STAT_FOLLOW_MOVE     = 0x00010000,
    UNIT_STAT_FLEEING         = 0x00020000,                 // FleeMovementGenerator/TimedFleeingMovementGenerator active/onstack
    UNIT_STAT_FLEEING_MOVE    = 0x00040000,
    // More room for other MMGens

    // High-Level states (usually only with Creatures)
    UNIT_STAT_NO_COMBAT_MOVEMENT    = 0x01000000,           // Combat Movement for MoveChase stopped
    UNIT_STAT_RUNNING               = 0x02000000,           // SetRun for waypoints and such
    UNIT_STAT_WAYPOINT_PAUSED       = 0x04000000,           // Waypoint-Movement paused genericly (ie by script)

    UNIT_STAT_IGNORE_PATHFINDING    = 0x10000000,           // do not use pathfinding in any MovementGenerator

    // masks (only for check)

    // can't move currently
    UNIT_STAT_CAN_NOT_MOVE    = UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DIED,

    // stay by different reasons
    UNIT_STAT_NOT_MOVE        = UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DIED |
    UNIT_STAT_DISTRACTED,

    // stay or scripted movement for effect( = in player case you can't move by client command)
    UNIT_STAT_NO_FREE_MOVE    = UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DIED |
    UNIT_STAT_TAXI_FLIGHT |
    UNIT_STAT_CONFUSED | UNIT_STAT_FLEEING,

    // not react at move in sight or other
    UNIT_STAT_CAN_NOT_REACT   = UNIT_STAT_STUNNED | UNIT_STAT_DIED |
    UNIT_STAT_CONFUSED | UNIT_STAT_FLEEING,

    // AI disabled by some reason
    UNIT_STAT_LOST_CONTROL    = UNIT_STAT_CONFUSED | UNIT_STAT_FLEEING | UNIT_STAT_CONTROLLED,

    // above 2 state cases
    UNIT_STAT_CAN_NOT_REACT_OR_LOST_CONTROL  = UNIT_STAT_CAN_NOT_REACT | UNIT_STAT_LOST_CONTROL,

    // masks (for check or reset)

    // for real move using movegen check and stop (except unstoppable flight)
    UNIT_STAT_MOVING          = UNIT_STAT_ROAMING_MOVE | UNIT_STAT_CHASE_MOVE | UNIT_STAT_FOLLOW_MOVE | UNIT_STAT_FLEEING_MOVE,

    UNIT_STAT_RUNNING_STATE   = UNIT_STAT_CHASE_MOVE | UNIT_STAT_FLEEING_MOVE | UNIT_STAT_RUNNING,

    UNIT_STAT_ALL_STATE       = 0xFFFFFFFF,
    UNIT_STAT_ALL_DYN_STATES  = UNIT_STAT_ALL_STATE & ~(UNIT_STAT_NO_COMBAT_MOVEMENT | UNIT_STAT_RUNNING | UNIT_STAT_WAYPOINT_PAUSED | UNIT_STAT_IGNORE_PATHFINDING)
};

enum UnitMoveType
{
    MOVE_WALK           = 0,
    MOVE_RUN            = 1,
    MOVE_RUN_BACK       = 2,
    MOVE_SWIM           = 3,
    MOVE_SWIM_BACK      = 4,
    MOVE_TURN_RATE      = 5
};

#define MAX_MOVE_TYPE     6

extern float baseMoveSpeed[MAX_MOVE_TYPE];

/// internal used flags for marking special auras - for example some dummy-auras
enum UnitAuraFlags
{
    UNIT_AURAFLAG_ALIVE_INVISIBLE   = 0x1,                  // aura which makes unit invisible for alive
};

enum UnitVisibility
{
    VISIBILITY_OFF                = 0,                      // absolute, not detectable, GM-like, can see all other
    VISIBILITY_ON                 = 1,
    VISIBILITY_GROUP_STEALTH      = 2,                      // detect chance, seen and can see group members
    VISIBILITY_GROUP_INVISIBILITY = 3,                      // invisibility, can see and can be seen only another invisible unit or invisible detection unit, set only if not stealthed, and in checks not used (mask used instead)
    VISIBILITY_GROUP_NO_DETECT    = 4,                      // state just at stealth apply for update Grid state. Don't remove, otherwise stealth spells will break
    VISIBILITY_REMOVE_CORPSE      = 5                       // special totally not detectable visibility for force delete object while removing a corpse
};

/**
 * [-ZERO] Need recheck values
 * Value masks for UNIT_FIELD_FLAGS (Taken from source)
 * \todo Document all the flags, not just the ones already commented
 */
enum UnitFlags
{
    UNIT_FLAG_NONE                  = 0x00000000,
    UNIT_FLAG_UNK_0                 = 0x00000001,
    UNIT_FLAG_NON_ATTACKABLE        = 0x00000002,           ///< not attackable
    UNIT_FLAG_CLIENT_CONTROL_LOST   = 0x00000004,           // Generic unspecified loss of control initiated by server script, movement checks disabled, paired with loss of client control packet.
    UNIT_FLAG_PVP_ATTACKABLE        = 0x00000008,           ///< allow apply pvp rules to attackable state in addition to faction dependent state, UNIT_FLAG_UNKNOWN1 in pre-bc mangos
    UNIT_FLAG_RENAME                = 0x00000010,           ///< rename creature
    UNIT_FLAG_RESTING               = 0x00000020,
    UNIT_FLAG_UNK_6                 = 0x00000040,
    UNIT_FLAG_OOC_NOT_ATTACKABLE    = 0x00000100,           ///< (OOC Out Of Combat) Can not be attacked when not in combat. Removed if unit for some reason enter combat (flag probably removed for the attacked and it's party/group only) \todo Needs more documentation
    UNIT_FLAG_PASSIVE               = 0x00000200,           ///< makes you unable to attack everything. Almost identical to our "civilian"-term. Will ignore it's surroundings and not engage in combat unless "called upon" or engaged by another unit.
    UNIT_FLAG_PVP                   = 0x00001000,
    UNIT_FLAG_SILENCED              = 0x00002000,           ///< silenced, 2.1.1
    UNIT_FLAG_UNK_14                = 0x00004000,           ///< 2.0.8
    UNIT_FLAG_UNK_15                = 0x00008000,           ///< related to jerky movement in water?
    UNIT_FLAG_UNK_16                = 0x00010000,           ///< removes attackable icon
    UNIT_FLAG_PACIFIED              = 0x00020000,
    UNIT_FLAG_DISABLE_ROTATE        = 0x00040000,
    UNIT_FLAG_IN_COMBAT             = 0x00080000,
    UNIT_FLAG_NOT_SELECTABLE        = 0x02000000,
    UNIT_FLAG_SKINNABLE             = 0x04000000,
    UNIT_FLAG_AURAS_VISIBLE         = 0x08000000,           ///< magic detect
    UNIT_FLAG_SHEATHE               = 0x40000000,
    // UNIT_FLAG_UNK_31              = 0x80000000           // no affect in 1.12.1

    UNIT_FLAG_NOT_ATTACKABLE_1      = 0x00000080,           ///< ?? (UNIT_FLAG_PVP_ATTACKABLE | UNIT_FLAG_NOT_ATTACKABLE_1) is NON_PVP_ATTACKABLE
    UNIT_FLAG_LOOTING               = 0x00000400,           ///< loot animation
    UNIT_FLAG_PET_IN_COMBAT         = 0x00000800,           ///< in combat?, 2.0.8
    UNIT_FLAG_STUNNED               = 0x00040000,           ///< stunned, 2.1.1
    UNIT_FLAG_TAXI_FLIGHT           = 0x00100000,           ///< disable casting at client side spell not allowed by taxi flight (mounted?), probably used with 0x4 flag
    UNIT_FLAG_DISARMED              = 0x00200000,           ///< disable melee spells casting..., "Required melee weapon" added to melee spells tooltip.
    UNIT_FLAG_CONFUSED              = 0x00400000,
    UNIT_FLAG_FLEEING               = 0x00800000,
    UNIT_FLAG_POSSESSED             = 0x01000000,           ///< used in spell Eyes of the Beast for pet... let attack by controlled creature |// Unit is under remote control by another unit, movement checks disabled, paired with loss of client control packet. New master is allowed to use melee attack and can't select this unit via mouse in the world (as if it was own character).
    UNIT_FLAG_UNK_28                = 0x10000000,
    UNIT_FLAG_UNK_29                = 0x20000000            ///< used in Feign Death spell
};

/**
 * Non Player Character flags
 * \todo Properly document this
 */
enum NPCFlags
{
    UNIT_NPC_FLAG_NONE                  = 0x00000000,
    UNIT_NPC_FLAG_GOSSIP                = 0x00000001,       ///< 100%
    UNIT_NPC_FLAG_QUESTGIVER            = 0x00000002,       ///< 100%
    UNIT_NPC_FLAG_VENDOR                = 0x00000004,       ///< 100%
    UNIT_NPC_FLAG_FLIGHTMASTER          = 0x00000008,       ///< 100%
    UNIT_NPC_FLAG_TRAINER               = 0x00000010,       ///< 100%
    UNIT_NPC_FLAG_SPIRITHEALER          = 0x00000020,       ///< guessed
    UNIT_NPC_FLAG_SPIRITGUIDE           = 0x00000040,       ///< guessed
    UNIT_NPC_FLAG_INNKEEPER             = 0x00000080,       ///< 100%
    UNIT_NPC_FLAG_BANKER                = 0x00000100,       ///< 100%
    UNIT_NPC_FLAG_PETITIONER            = 0x00000200,       ///< 100% 0xC0000 = guild petitions
    UNIT_NPC_FLAG_TABARDDESIGNER        = 0x00000400,       ///< 100%
    UNIT_NPC_FLAG_BATTLEMASTER          = 0x00000800,       ///< 100%
    UNIT_NPC_FLAG_AUCTIONEER            = 0x00001000,       ///< 100%
    UNIT_NPC_FLAG_STABLEMASTER          = 0x00002000,       ///< 100%
    UNIT_NPC_FLAG_REPAIR                = 0x00004000,       ///< 100%
    UNIT_NPC_FLAG_OUTDOORPVP            = 0x20000000        ///< custom flag for outdoor pvp creatures || Custom flag
};

/**
 * These flags denote the different kinds of movement you can do. You can have many at the
 * same time as this is used as a bitmask.
 * \todo [-ZERO] Need check and update used in most movement packets (send and received)
 * \see MovementInfo
 */
enum MovementFlags
{
    MOVEFLAG_NONE             = 0x00000000,
    MOVEFLAG_FORWARD          = 0x00000001,
    MOVEFLAG_BACKWARD         = 0x00000002,
    MOVEFLAG_STRAFE_LEFT      = 0x00000004,
    MOVEFLAG_STRAFE_RIGHT     = 0x00000008,
    MOVEFLAG_TURN_LEFT        = 0x00000010,
    MOVEFLAG_TURN_RIGHT       = 0x00000020,
    MOVEFLAG_PITCH_UP         = 0x00000040,
    MOVEFLAG_PITCH_DOWN       = 0x00000080,
    MOVEFLAG_WALK_MODE        = 0x00000100,               // Walking

    MOVEFLAG_LEVITATING       = 0x00000400,
    MOVEFLAG_FLYING           = 0x00000800,               // [-ZERO] is it really need and correct value
    MOVEFLAG_FALLING          = 0x00002000,
    MOVEFLAG_FALLINGFAR       = 0x00004000,
    MOVEFLAG_SWIMMING         = 0x00200000,               // appears with fly flag also
    MOVEFLAG_SPLINE_ENABLED   = 0x00400000,
    MOVEFLAG_CAN_FLY          = 0x00800000,               // [-ZERO] is it really need and correct value
    MOVEFLAG_FLYING_OLD       = 0x01000000,               // [-ZERO] is it really need and correct value

    MOVEFLAG_ONTRANSPORT      = 0x02000000,               // Used for flying on some creatures
    MOVEFLAG_SPLINE_ELEVATION = 0x04000000,               // used for flight paths
    MOVEFLAG_ROOT             = 0x08000000,               // used for flight paths
    MOVEFLAG_WATERWALKING     = 0x10000000,               // prevent unit from falling through water
    MOVEFLAG_SAFE_FALL        = 0x20000000,               // active rogue safe fall spell (passive)
    MOVEFLAG_HOVER            = 0x40000000
};

// flags that use in movement check for example at spell casting
MovementFlags const movementFlagsMask = MovementFlags(
    MOVEFLAG_FORWARD | MOVEFLAG_BACKWARD | MOVEFLAG_STRAFE_LEFT | MOVEFLAG_STRAFE_RIGHT |
    MOVEFLAG_PITCH_UP | MOVEFLAG_PITCH_DOWN | MOVEFLAG_ROOT |
    MOVEFLAG_FALLING | MOVEFLAG_FALLINGFAR | MOVEFLAG_SPLINE_ELEVATION
    );

MovementFlags const movementOrTurningFlagsMask = MovementFlags(
            movementFlagsMask | MOVEFLAG_TURN_LEFT | MOVEFLAG_TURN_RIGHT
        );

class MovementInfo
{
    public:
        MovementInfo() : moveFlags(MOVEFLAG_NONE), time(0),
            t_time(0), s_pitch(0.0f), fallTime(0), u_unk1(0.0f) {}

        // Read/Write methods
        void Read(ByteBuffer& data);
        void Write(ByteBuffer& data) const;

        // Movement flags manipulations
        void AddMovementFlag(MovementFlags f) { moveFlags |= f; }
        void RemoveMovementFlag(MovementFlags f) { moveFlags &= ~f; }
        bool HasMovementFlag(MovementFlags f) const { return moveFlags & f; }
        MovementFlags GetMovementFlags() const { return MovementFlags(moveFlags); }
        void SetMovementFlags(MovementFlags f) { moveFlags = f; }

        // Position manipulations
        Position const* GetPos() const { return &pos; }
        void SetTransportData(ObjectGuid guid, float x, float y, float z, float o, uint32 time)
        {
            t_guid = guid;
            t_pos.x = x;
            t_pos.y = y;
            t_pos.z = z;
            t_pos.o = o;
            t_time = time;
        }
        void ClearTransportData()
        {
            t_guid = ObjectGuid();
            t_pos.x = 0.0f;
            t_pos.y = 0.0f;
            t_pos.z = 0.0f;
            t_pos.o = 0.0f;
            t_time = 0;
        }
        ObjectGuid const& GetTransportGuid() const { return t_guid; }
        Position const* GetTransportPos() const { return &t_pos; }
        uint32 GetTime() { return time; }
        uint32 GetTransportTime() const { return t_time; }
        uint32 GetFallTime() const { return fallTime; }
        void ChangeOrientation(float o) { pos.o = o; }
        void ChangePosition(float x, float y, float z, float o) { pos.x = x; pos.y = y; pos.z = z; pos.o = o; }
        void UpdateTime(uint32 _time) { time = _time; }

        struct JumpInfo
        {
            JumpInfo() : velocity(0.f), sinAngle(0.f), cosAngle(0.f), xyspeed(0.f) {}
            float   velocity, sinAngle, cosAngle, xyspeed;
        };

        JumpInfo const& GetJumpInfo() const { return jump; }
    private:
        // common
        uint32   moveFlags;                                 // see enum MovementFlags
        uint32   time;
        Position pos;
        // transport
        ObjectGuid t_guid;
        Position t_pos;
        uint32   t_time;
        // swimming and unknown
        float    s_pitch;
        // last fall time
        uint32   fallTime;
        // jumping
        JumpInfo jump;
        // spline
        float    u_unk1;
};

inline ByteBuffer& operator<< (ByteBuffer& buf, MovementInfo const& mi)
{
    mi.Write(buf);
    return buf;
}

inline ByteBuffer& operator>> (ByteBuffer& buf, MovementInfo& mi)
{
    mi.Read(buf);
    return buf;
}

namespace Movement
{
    class MoveSpline;
}

/**
 * The different available diminishing return levels.
 * \see DiminishingReturn
 */
enum DiminishingLevels
{
    DIMINISHING_LEVEL_1             = 0,         ///<Won't make a difference to stun duration
    DIMINISHING_LEVEL_2             = 1,         ///<Reduces stun time by 50%
    DIMINISHING_LEVEL_3             = 2,         ///<Reduces stun time by 75%
    DIMINISHING_LEVEL_IMMUNE        = 3          ///<The target is immune to the DiminishingGrouop
};

/**
 * Structure to keep track of diminishing returns, for more information
 * about the idea behind diminishing returns, see: http://www.wowwiki.com/Diminishing_returns
 * \see Unit::GetDiminishing
 * \see Unit::IncrDiminishing
 * \see Unit::ApplyDiminishingToDuration
 * \see Unit::ApplyDiminishingAura
 */
struct DiminishingReturn
{
    DiminishingReturn(DiminishingGroup group, uint32 t, uint32 count)
        : DRGroup(group), stack(0), hitTime(t), hitCount(count)
    {}

    /**
     * Group that this diminishing return will affect
     */
    DiminishingGroup        DRGroup: 16;
    /**
     * Seems to be how many times this has been stacked, modified in
     * Unit::ApplyDiminishingAura
     */
    uint16                  stack: 16;
    /**
     * Records at what time the last hit with this DiminishingGroup was done, if it's
     * higher than 15 seconds (ie: 15 000 ms) the DiminishingReturn::hitCount will be reset
     * to DiminishingLevels::DIMINISHING_LEVEL_1, which will do no difference to the duration
     * of the stun etc.
     */
    uint32                  hitTime;
    /**
     * Records how many times a spell of this DiminishingGroup has hit, this in turn
     * decides how how long the duration of the stun etc is.
     */
    uint32                  hitCount;
};

/**
 * At least some values expected fixed and used in auras field, other custom
 */
enum MeleeHitOutcome
{
    MELEE_HIT_EVADE     = 0,
    MELEE_HIT_MISS      = 1,
    MELEE_HIT_DODGE     = 2,     ///< used as misc in SPELL_AURA_IGNORE_COMBAT_RESULT
    MELEE_HIT_BLOCK     = 3,     ///< used as misc in SPELL_AURA_IGNORE_COMBAT_RESULT
    MELEE_HIT_PARRY     = 4,     ///< used as misc in SPELL_AURA_IGNORE_COMBAT_RESULT
    MELEE_HIT_GLANCING  = 5,
    MELEE_HIT_CRIT      = 6,
    MELEE_HIT_CRUSHING  = 7,
    MELEE_HIT_NORMAL    = 8,
    MELEE_HIT_BLOCK_CRIT = 9,
};

struct CleanDamage
{
    CleanDamage(uint32 _damage, WeaponAttackType _attackType, MeleeHitOutcome _hitOutCome) :
        damage(_damage), attackType(_attackType), hitOutCome(_hitOutCome) {}

    uint32 damage;
    WeaponAttackType attackType;
    MeleeHitOutcome hitOutCome;
};

/**
 * Struct for use in Unit::CalculateMeleeDamage
 * Need create structure like in SMSG_ATTACKERSTATEUPDATE opcode
 */
struct CalcDamageInfo
{
    /// Attacker
    Unit*  attacker;
    /// Target for damage
    Unit*  target;
    SpellSchoolMask damageSchoolMask;
    /// How much damage was actually done
    uint32 damage;
    /// How much damage that was absorbed
    uint32 absorb;
    /// How much of the damage that was resisted
    uint32 resist;
    /// How much of the damage that was blocked
    uint32 blocked_amount;
    /**
     * Bitmask of the possible HitInfo flags
     * \see HitInfo
     */
    uint32 HitInfo;
    /**
     * What state the target is in, ie: is he evading or deflecting the hit?
     * \see VictimState
     */
    uint32 TargetState;
    /**
     * Tells how the target was attacked
     */
    WeaponAttackType attackType;
    /**
     * Proc flags of the attacker that should have a chance to trigger, ie: successful
     * melee hit
     * \see ProcFlags
     */
    uint32 procAttacker;
    /**
     * Proc flags of the victim that should have a change to trigger, ie: successful
     * block
     * \see ProcFlags
     */
    uint32 procVictim;
    /**
     * Extra proc flags?
     * \todo Used for what?
     */
    uint32 procEx;
    /// Used only for rage calculation
    uint32 cleanDamage;
    /// (Old comment) \todo remove this field (need use TargetState)
    MeleeHitOutcome hitOutCome;
};

/**
 * Spell damage info structure based on structure sending in SMSG_SPELLNONMELEEDAMAGELOG opcode
 */
struct SpellNonMeleeDamage
{
    SpellNonMeleeDamage(Unit* _attacker, Unit* _target, uint32 _SpellID, SpellSchools _school)
        : target(_target), attacker(_attacker), SpellID(_SpellID), damage(0), school(_school),
          absorb(0), resist(0), physicalLog(false), unused(false), blocked(0), HitInfo(0)
    {}

    Unit*   target;
    Unit*   attacker;
    uint32 SpellID;
    uint32 damage;
    SpellSchools school;
    uint32 absorb;
    uint32 resist;
    bool   physicalLog;
    bool   unused;
    uint32 blocked;
    uint32 HitInfo;
};

/**
 * Used as a convenience struct for the \ref Unit::SendPeriodicAuraLog
 * \todo Is it used in more places? Check SpellAuras.cpp for some examples and document it
 */
struct SpellPeriodicAuraLogInfo
{
    SpellPeriodicAuraLogInfo(Aura* _aura, uint32 _damage, uint32 _absorb, uint32 _resist, float _multiplier)
        : aura(_aura), damage(_damage), absorb(_absorb), resist(_resist), multiplier(_multiplier) {}

    Aura*   aura;       ///< The \ref Aura in question
    uint32 damage;      ///< How much damage this does or how much it adds if it's a positive \ref Aura
    uint32 absorb;      ///< The amount that was absorbed
    uint32 resist;      ///< The amount that was resisted
    float  multiplier;  ///< The multiplier for gain, ie if it's higher you gain more probably
};

uint32 createProcExtendMask(SpellNonMeleeDamage* damageInfo, SpellMissInfo missCondition);

enum SpellAuraProcResult
{
    SPELL_AURA_PROC_OK              = 0,                    // proc was processed, will remove charges
    SPELL_AURA_PROC_FAILED          = 1,                    // proc failed - if at least one aura failed the proc, charges won't be taken
    SPELL_AURA_PROC_CANT_TRIGGER    = 2                     // aura can't trigger - skip charges taking, move to next aura if exists
};

typedef SpellAuraProcResult(Unit::*pAuraProcHandler)(Unit* pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const* procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown);
extern pAuraProcHandler AuraProcHandler[TOTAL_AURAS];

enum CurrentSpellTypes
{
    CURRENT_MELEE_SPELL             = 0,
    CURRENT_GENERIC_SPELL           = 1,
    CURRENT_AUTOREPEAT_SPELL        = 2,
    CURRENT_CHANNELED_SPELL         = 3
};

#define CURRENT_FIRST_NON_MELEE_SPELL 1
#define CURRENT_MAX_SPELL             4

struct GlobalCooldown
{
    explicit GlobalCooldown(uint32 _dur = 0, uint32 _time = 0) : duration(_dur), cast_time(_time) {}

    uint32 duration;
    uint32 cast_time;
};

typedef UNORDERED_MAP < uint32 /*category*/, GlobalCooldown > GlobalCooldownList;

class GlobalCooldownMgr                                     // Shared by Player and CharmInfo
{
    public:
        GlobalCooldownMgr() {}

    public:
        bool HasGlobalCooldown(SpellEntry const* spellInfo) const;
        void AddGlobalCooldown(SpellEntry const* spellInfo, uint32 gcd);
        void CancelGlobalCooldown(SpellEntry const* spellInfo);

    private:
        GlobalCooldownList m_GlobalCooldowns;
};

enum ActiveStates
{
    ACT_PASSIVE  = 0x01,                                    // 0x01 - passive
    ACT_DISABLED = 0x81,                                    // 0x80 - castable
    ACT_ENABLED  = 0xC1,                                    // 0x40 | 0x80 - auto cast + castable
    ACT_COMMAND  = 0x07,                                    // 0x01 | 0x02 | 0x04
    ACT_REACTION = 0x06,                                    // 0x02 | 0x04
    ACT_DECIDE   = 0x00                                     // custom
};

enum ReactStates
{
    REACT_PASSIVE    = 0,
    REACT_DEFENSIVE  = 1,
    REACT_AGGRESSIVE = 2
};

enum CommandStates
{
    COMMAND_STAY    = 0,
    COMMAND_FOLLOW  = 1,
    COMMAND_ATTACK  = 2,
    COMMAND_ABANDON = 3
};

#define UNIT_ACTION_BUTTON_ACTION(X) (uint32(X) & 0x00FFFFFF)
#define UNIT_ACTION_BUTTON_TYPE(X)   ((uint32(X) & 0xFF000000) >> 24)
#define MAX_UNIT_ACTION_BUTTON_ACTION_VALUE (0x00FFFFFF+1)
#define MAKE_UNIT_ACTION_BUTTON(A,T) (uint32(A) | (uint32(T) << 24))

struct UnitActionBarEntry
{
    UnitActionBarEntry() : packedData(uint32(ACT_DISABLED) << 24) {}

    uint32 packedData;

    // helper
    ActiveStates GetType() const { return ActiveStates(UNIT_ACTION_BUTTON_TYPE(packedData)); }
    uint32 GetAction() const { return UNIT_ACTION_BUTTON_ACTION(packedData); }
    bool IsActionBarForSpell() const
    {
        ActiveStates Type = GetType();
        return Type == ACT_DISABLED || Type == ACT_ENABLED || Type == ACT_PASSIVE;
    }

    void SetActionAndType(uint32 action, ActiveStates type)
    {
        packedData = MAKE_UNIT_ACTION_BUTTON(action, type);
    }

    void SetType(ActiveStates type)
    {
        packedData = MAKE_UNIT_ACTION_BUTTON(UNIT_ACTION_BUTTON_ACTION(packedData), type);
    }

    void SetAction(uint32 action)
    {
        packedData = (packedData & 0xFF000000) | UNIT_ACTION_BUTTON_ACTION(action);
    }
};

typedef UnitActionBarEntry CharmSpellEntry;

enum ActionBarIndex
{
    ACTION_BAR_INDEX_START = 0,
    ACTION_BAR_INDEX_PET_SPELL_START = 3,
    ACTION_BAR_INDEX_PET_SPELL_END = 7,
    ACTION_BAR_INDEX_END = 10,
};

#define MAX_UNIT_ACTION_BAR_INDEX (ACTION_BAR_INDEX_END-ACTION_BAR_INDEX_START)

/**
 * This structure/class is used when someone is charming (ie: mind control spell and the like)
 * someone else, to get the charmed ones action bar, the spells and such. It also takes care
 * of pets the charmed one has etc.
 */
struct CharmInfo
{
    public:
        explicit CharmInfo(Unit* unit);
        uint32 GetPetNumber() const { return m_petnumber; }
        void SetPetNumber(uint32 petnumber, bool statwindow);

        void SetCommandState(CommandStates st) { m_CommandState = st; }
        CommandStates GetCommandState() { return m_CommandState; }
        bool HasCommandState(CommandStates state) { return (m_CommandState == state); }
        void SetReactState(ReactStates st) { m_reactState = st; }
        ReactStates GetReactState() { return m_reactState; }
        bool HasReactState(ReactStates state) { return (m_reactState == state); }

        void InitPossessCreateSpells();
        void InitCharmCreateSpells();
        void InitPetActionBar();
        void InitEmptyActionBar();

        // return true if successful
        bool AddSpellToActionBar(uint32 spellid, ActiveStates newstate = ACT_DECIDE);
        bool RemoveSpellFromActionBar(uint32 spell_id);
        void LoadPetActionBar(const std::string& data);
        void BuildActionBar(WorldPacket* data);
        void SetSpellAutocast(uint32 spell_id, bool state);
        void SetActionBar(uint8 index, uint32 spellOrAction, ActiveStates type)
        {
            PetActionBar[index].SetActionAndType(spellOrAction, type);
        }
        UnitActionBarEntry const* GetActionBarEntry(uint8 index) const { return &(PetActionBar[index]); }

        void ToggleCreatureAutocast(uint32 spellid, bool apply);

        CharmSpellEntry* GetCharmSpell(uint8 index) { return &(m_charmspells[index]); }

        GlobalCooldownMgr& GetGlobalCooldownMgr() { return m_GlobalCooldownMgr; }

    private:
        Unit* m_unit;
        UnitActionBarEntry PetActionBar[MAX_UNIT_ACTION_BAR_INDEX];
        CharmSpellEntry m_charmspells[CREATURE_MAX_SPELLS];
        CommandStates   m_CommandState;
        ReactStates     m_reactState;
        uint32          m_petnumber;
        GlobalCooldownMgr m_GlobalCooldownMgr;
};

// used in CallForAllControlledUnits/CheckAllControlledUnits
enum ControlledUnitMask
{
    CONTROLLED_PET       = 0x01,
    CONTROLLED_MINIPET   = 0x02,
    CONTROLLED_GUARDIANS = 0x04,                            // including PROTECTOR_PET
    CONTROLLED_CHARM     = 0x08,
    CONTROLLED_TOTEMS    = 0x10,
};

// for clearing special attacks
#define REACTIVE_TIMER_START 4000

enum ReactiveType
{
    REACTIVE_DEFENSE      = 1,
    REACTIVE_HUNTER_PARRY = 2,
    REACTIVE_OVERPOWER    = 5
};

#define MAX_REACTIVE 6

// delay time next attack to prevent client attack animation problems
#define ATTACK_DISPLAY_DELAY 200
#define MAX_PLAYER_STEALTH_DETECT_RANGE 45.0f               // max distance for detection targets by player
#define MAX_CREATURE_ATTACK_RADIUS 45.0f                    // max distance for creature aggro (use with CONFIG_FLOAT_RATE_CREATURE_AGGRO)

// Regeneration defines
#define REGEN_TIME_FULL     2000                            // For this time difference is computed regen value

// Power type values defines
enum PowerDefaults
{
    POWER_RAGE_DEFAULT              = 1000,
    POWER_FOCUS_DEFAULT             = 100,
    POWER_ENERGY_DEFAULT            = 100,
    POWER_HAPPINESS_DEFAULT         = 1000000,
};

struct SpellProcEventEntry;                                 // used only privately

class Unit : public WorldObject
{
    public:
        typedef std::set<Unit*> AttackerSet;
        /**
         * A multimap from spell ids to \ref SpellAuraHolder, multiple \ref SpellAuraHolder can have
         * the same id (ie: the same key)
         */
        typedef std::multimap < uint32 /*spellId*/, SpellAuraHolder* > SpellAuraHolderMap;
        /**
         * A pair of two iterators to a \ref SpellAuraHolderMap which is used in conjunction
         * with the std::multimap::equal_range which gives all \ref SpellAuraHolder that have the same
         * spellid in this case, the first member is the iterator to the beginning, and the
         * second member is the iterator to the end.
         */
        typedef std::pair<SpellAuraHolderMap::iterator, SpellAuraHolderMap::iterator> SpellAuraHolderBounds;
        /// Same thing as \ref SpellAuraHolderBounds but with const_iterator instead of iterator
        typedef std::pair<SpellAuraHolderMap::const_iterator, SpellAuraHolderMap::const_iterator> SpellAuraHolderConstBounds;
        typedef std::list<SpellAuraHolder*> SpellAuraHolderList;
        /**
         * List of \ref Aura used in \ref Unit::GetAurasByType and more and also in the members
         * \ref Unit::m_modAuras and \ref Unit::m_deletedAuras
         * \see Aura
         */
        typedef std::list<Aura*> AuraList;
        /**
         * List of \ref DiminishingReturn used for calculation of the same thing.
         * \see DiminishingReturn
         * \see DiminishingLevels
         * \see Unit::GetDiminishing
         * \see Unit::IncrDiminishing
         * \see Unit::ApplyDiminishingToDuration
         */
        typedef std::list<DiminishingReturn> Diminishing;
        typedef std::set < uint32 /*playerGuidLow*/ > ComboPointHolderSet;
        typedef std::map < SpellEntry const*, ObjectGuid /*targetGuid*/ > TrackedAuraTargetMap;

        virtual ~Unit();

        //These are probably interesting for learning how/when objects/units get added to the
        //world, take a look at them and write something tutorialishy about it to introduce
        //more of how the core works?
        void AddToWorld() override;
        void RemoveFromWorld() override;

        /**
         * Used in ~Creature/~Player (or before mass creature delete to remove
         * cross-references to already deleted units). (Taken from comment in source)
         * \todo Add more information here
         */
        void CleanupsBeforeDelete() override;

        bool IsControlledByPlayer() const override
        {
            return IsCharmerOrOwnerPlayerOrPlayerItself();
        }

        float GetObjectBoundingRadius() const override      // overwrite WorldObject version
        {
            return m_floatValues[UNIT_FIELD_BOUNDINGRADIUS];
        }

        /**
         * Gets the current DiminishingLevels for the given group
         * @param group The group that you would like to know the current diminishing return level for
         * @return The current diminishing level, up to DiminishingLevels::DIMINISHING_LEVEL_IMMUNE
         */
        DiminishingLevels GetDiminishing(DiminishingGroup  group);
        /**
         * Increases the level of the DiminishingGroup by one level up until
         * DIMINISHING_LEVEL_IMMUNE where the target becomes immune to spells of
         * that DiminishingGroup
         * @param group The group to increase the level for by one
         */
        void IncrDiminishing(DiminishingGroup group);
        /**
         * Calculates how long the duration of a spell should be considering
         * diminishing returns, ie, if the Level passed in is DIMINISHING_LEVEL_IMMUNE
         * then the duration will be zeroed out. If it is DIMINISHING_LEVEL_1 then a full
         * duration will be used
         * @param group The group to affect
         * @param duration The duration to be changed, will be updated with the new duration
         * @param caster Who's casting the spell, used to decide whether anything should be calculated
         * @param Level The current level of diminishing returns for the group, decides the new duration
         * @param isReflected Whether the spell was reflected or not, used to determine if we should do any calculations at all.
         */
        void ApplyDiminishingToDuration(DiminishingGroup  group, int32& duration, Unit* caster, DiminishingLevels Level, bool isReflected);
        /**
         * Applies a diminishing return to the given group if apply is true,
         * otherwise lowers the level by one (?)
         * @param group The group to affect
         * @param apply whether this aura is being added/removed
         */
        void ApplyDiminishingAura(DiminishingGroup  group, bool apply);
        /**
         * Clears all the current diminishing returns for this Unit.
         */
        void ClearDiminishings() { m_Diminishing.clear(); }

        void Update(uint32 update_diff, uint32 time) override;

        /**
         * Updates the attack time for the given WeaponAttackType
         * @param type The type of weapon that we want to update the time for
         * @param time the remaining time until we can attack with the WeaponAttackType again
         */
        void setAttackTimer(WeaponAttackType type, uint32 time) { m_attackTimer[type] = time; }
        /**
         * Resets the attack timer to the base value decided by Unit::m_modAttackSpeedPct and
         * Unit::GetAttackTime
         * @param type The weapon attack type to reset the attack timer for.
         */
        void resetAttackTimer(WeaponAttackType type = BASE_ATTACK);
        /**
         * Get's the remaining time until we can do an attack
         * @param type The weapon type to check the remaining time for
         * @return The remaining time until we can attack with this weapon type.
         */
        uint32 getAttackTimer(WeaponAttackType type) const { return m_attackTimer[type]; }
        /**
         * Checks whether the unit can do an attack. Does this by checking the attacktimer for the
         * WeaponAttackType, can probably be thought of as a cooldown for each swing/shot
         * @param type What weapon should we check for
         * @return true if the Unit::m_attackTimer is zero for the given WeaponAttackType
         */
        bool isAttackReady(WeaponAttackType type = BASE_ATTACK) const { return m_attackTimer[type] == 0; }
        /**
         * Checks if the current Unit has an offhand weapon
         * @return True if there is a offhand weapon.
         */
        bool haveOffhandWeapon() const;
        /**
         * Does an attack if any of the timers allow it and resets them, if the user
         * isn't in range or behind the target an error is sent to the client.
         * Also makes sure to not make and offhand and mainhand attack at the same
         * time. Only handles non-spells ie melee attacks.
         * @return True if an attack was made and no error happened, false otherwise
         */
        bool UpdateMeleeAttackingState();
        /**
         * Check is a given equipped weapon can be used, ie the mainhand, offhand etc.
         * @param attackType The attack type to check, ie: main/offhand/ranged
         * @return True if the weapon can be used, true except for shapeshifts and if disarmed.
         */
        bool CanUseEquippedWeapon(WeaponAttackType attackType) const
        {
            if (IsInFeralForm())
            {
                return false;
            }

            switch (attackType)
            {
                default:
                case BASE_ATTACK:
                    return !HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISARMED);
                case OFF_ATTACK:
                case RANGED_ATTACK:
                    return true;
            }
        }

        /**
         * Returns the combined combat reach of two mobs. Can be seen as a radius.
         * @param pVictim The other unit to add the range for
         * @param forMeleeRange Whether we should return the combined reach for melee or not
         * @param flat_mod Increases the returned reach by this value.
         * @return The combined values of UNIT_FIELD_COMBATREACH for both this unit and the pVictim.
         * \see EUnitFields
         * \see GetFloatValue
         */
        float GetCombatReach(Unit const* pVictim, bool forMeleeRange = true, float flat_mod = 0.0f) const;
        /**
         * Returns the remaining combat distance between two mobs (CombatReach substracted).
         * Does this by getting the radius of combat/aggro between them and then subtracting their
         * actual distance between them. Ie: dist between - radius for aggro. If this becomes less
         * than zero zero is returned and the mobs should probably aggro each other/the player
         * @param target The target to check against
         * @param forMeleeRange If we want to check melee range instead
         * @return The reach between them left until one of the creatures could/should aggro
         */
        float GetCombatDistance(Unit const* target, bool forMeleeRange) const;
        /**
         * Returns if the Unit can reach a victim with Melee Attack. Does so by using
         * Unit::GetCombatReach for melee and checking if the distance from the target is less than
         * the reach.
         * @param pVictim Who we want to reach with a melee attack.
         * @param flat_mod The same as sent to Unit::GetCombatReach
         * @return true if we can reach pVictim with a melee attack
         */
        bool CanReachWithMeleeAttack(Unit const* pVictim, float flat_mod = 0.0f) const;
        uint32 m_extraAttacks;

        /**
         * Internal function, must only be called from Unit::Attack(Unit*)
         * @param pAttacker The attacker to add to current attackers.
         */
        void _addAttacker(Unit* pAttacker)                  // must be called only from Unit::Attack(Unit*)
        {
            AttackerSet::const_iterator itr = m_attackers.find(pAttacker);
            if (itr == m_attackers.end())
            {
                m_attackers.insert(pAttacker);
            }
        }
        /**
         * Internal function, must only be called from Unit::AttackStop()
         * @param pAttacker
         */
        void _removeAttacker(Unit* pAttacker)               // must be called only from Unit::AttackStop()
        {
            m_attackers.erase(pAttacker);
        }
        /**
         * If another mob/unit want to help this mob this function will return a
         * possible Unit to attack.
         * @return A Unit to attack if this one is being attacked by anyone, NULL otherwise
         */
        Unit* getAttackerForHelper()                        // If someone wants to help, who to give them
        {
            if (getVictim() != NULL)
            {
                return getVictim();
            }

            if (!m_attackers.empty())
            {
                return *(m_attackers.begin());
            }

            return NULL;
        }
        /**
         * Tries to attack a Unit/Player, also makes sure to stop attacking the current target
         * if we're already attacking someone.
         * @param victim The Unit to attack
         * @param meleeAttack Whether we should attack with melee or ranged/magic
         * @return True if an attack was initiated, false otherwise
         */
        bool Attack(Unit* victim, bool meleeAttack);
        /**
         * Called when we are attack by someone in someway, might be when a fear runs out and
         * we want to notify AI to attack again or when a spell hits.
         * @param attacker Who's attacking us
         */
        void AttackedBy(Unit* attacker);
        /**
         * Stop all spells from casting except the one give by except_spellid
         * @param except_spellid This spell id will not be stopped from casting, defaults to 0
         * \see Unit::InterruptSpell
         */
        void CastStop(uint32 except_spellid = 0);
        /**
         * Stops attacking whatever we are attacking at the moment and tells the Unit we are attacking
         * that we are not doing that anymore, ie: removes it from the attacker list
         * @param targetSwitch if we are switching targets or not, defaults to false
         * @return false if we weren't attacking already, true otherwise
         * \see Unit::m_attacking
         */
        bool AttackStop(bool targetSwitch = false);
        /**
         * Removes all attackers from the Unit::m_attackers set and logs it if someone that
         * wasn't attacking it was in the list. Does this check by checking if Unit::AttackStop()
         * returned false.
         * \see Unit::AttackStop
         */
        void RemoveAllAttackers();
        /**
         * @return The Unit::m_attackers, ie. the units that are attacking you
         */
        AttackerSet const& getAttackers() const { return m_attackers; }
        /**
         * Checks if we are attacking a player, also, pets/minions etc attacking a player counts
         * towards you attacking a player.
         * @return true if you and/or your pets/minions etc are attacking a player.
         * \todo Rename to IsAttackingPlayer to follow naming conventions?
         */
        bool isAttackingPlayer() const;
        /**
         * @return The victim that you are currently attacking
         */
        Unit* getVictim() const { return m_attacking; }
        /**
         * Stops a unit from combat, removes all attackers and stops attacking.
         * @param includingCast if we should stop the currently casting spell aswell
         */
        void CombatStop(bool includingCast = false);
        /**
         * Calls Unit::CombatStop to stop combat, also calls Unit::CombatStop for pets etc. by using
         * Unit::CallForAllControlledUnits
         * @param includingCast if we should stop the currently casting spell aswell
         * \see Unit::CallForAllControlledUnits
         * \see Unit::CheckForAllControlledUnits
         */
        void CombatStopWithPets(bool includingCast = false);
        /**
         * Stops attacking a certain faction. If we are attacking something and are a player we
         * are forcefully stopped from attacking the target aswell.
         * @param faction_id The faction to stop attacking
         * \see Unit::CallForAllControlledUnits
         * \see Unit::CheckForAllControlledUnits
         * \see Unit::getAttackers
         */
        void StopAttackFaction(uint32 faction_id);
        /**
         * Selects a random unfriendly target, takes care of LOS and such aswell
         * @param except select any target but this one, usually your current target
         * @param radius how big the radius for our search should be
         * @return The random unfriendly target found, NULL if no targets were found
         * \see MaNGOS::AnyUnfriendlyUnitInObjectRangeCheck
         * \see Mangos::UnitListSearcher
         * \see Cell::VisitAllObjects
         */
        Unit* SelectRandomUnfriendlyTarget(Unit* except = NULL, float radius = ATTACK_DISTANCE) const;
        /**
         * Same as Unit::SelectRandomUnfriendlyTarget except it selects a friendly target
         * @param except select any target but this one, usually your current target
         * @param radius how big the radius for our search should be
         * @return The random friendly target found, NULL if no targets were found
         * \see MaNGOS::AnyFriendlyUnitInObjectRangeCheck
         * \see Mangos::UnitListSearcher
         * \see Cell::VisitAllObjects
         */
        Unit* SelectRandomFriendlyTarget(Unit* except = NULL, float radius = ATTACK_DISTANCE) const;
        /**
        * @param fRange how big the radius for our search should be
        * @param uiMinHPDiff how much health the unit has to be missing
        * @param bPercent if the previous param is percent or raw value
        * @param except select any target but this one, usually your current target
        * @return The injured friendly target found, NULL if no targets were found
        * \see Mangos::UnitListSearcher
        * \see Cell::VisitAllObjects
        */
        Unit* FindLowestHpFriendlyUnit(float fRange, uint32 uiMinHPDiff = 1, bool bPercent = false, Unit* except = nullptr) const;
        /**
        * @param range how big the radius for our search should be
        * @param spellid buff to check
        * @param except select any target but this one, usually your current target
        * @return The friendly target found, NULL if no targets were found
        * \see Mangos::UnitListSearcher
        * \see Cell::VisitAllObjects
        */
        Unit* FindFriendlyUnitMissingBuff(float range, uint32 spellid, Unit* except = nullptr) const;
        /**
        * @param range how big the radius for our search should be
        * @return The friendly target found, NULL if no targets were found
        * \see Mangos::UnitListSearcher
        * \see Cell::VisitAllObjects
        */
        Unit* FindFriendlyUnitCC(float range) const;
        /**
         * Checks if we have a negative aura with the given interrupt flag/s
         * @param flag The interrupt flag/s to check for, see SpellAuraInterruptFlags
         * @return true if we have a negative aura with the given flag, false otherwise
         * \see SpellAuraInterruptFlags
         */
        bool hasNegativeAuraWithInterruptFlag(uint32 flag);
        /**
         * Sends a packet to the client informing it that melee attacks are stopping
         * @param victim The unit we stopped attacking
         * \see OpcodesList
         */
        void SendMeleeAttackStop(Unit* victim);
        /**
         * Sends a packet to the client informing it that melee attacks are starting
         * @param pVictim the target that we attack with melee
         */
        void SendMeleeAttackStart(Unit* pVictim);

        /**
         * Adds a state to this unit
         * @param f the state to add, see UnitState for possible values
         * \see UnitState
         */
        void addUnitState(uint32 f) { m_state |= f; }
        /**
         * Checks if a certain unit state is set
         * @param f the state to check for
         * @return true if the state is set, false otherwise
         * \see UnitState
         */
        bool hasUnitState(uint32 f) const { return (m_state & f); }
        /**
         * Unsets a certain unit state
         * @param f the state to remove
         * \see UnitState
         */
        void clearUnitState(uint32 f) { m_state &= ~f; }
        /**
         * Checks if the client/mob is in control or no
         * @return true if the client can move by client control, false otherwise
         * \see UnitState
         */
        bool CanFreeMove() const
        {
            return !hasUnitState(UNIT_STAT_NO_FREE_MOVE) && !GetOwnerGuid();
        }

        /**
         * Gets the level for this unit
         * @return The current level for this unit
         * \see GetUInt32Value
         * \see EUnitFields
         */
        uint32 getLevel() const { return GetUInt32Value(UNIT_FIELD_LEVEL); }
        /**
         * @return The level it would seem
         * \todo What does it actually do? Is overwritten by others that derive from Unit?
         */
        virtual uint32 GetLevelForTarget(Unit const* /*target*/) const { return getLevel(); }
        /**
         * Updates the level for the current Unit. Also updates the group to know about this.
         * @param lvl The level to change to
         * \see EUnitFields
         * \see SetUInt32Value
         */
        void SetLevel(uint32 lvl);
        /**
         * Gets the race of this Unit, not to be confused with the Creature type or such
         * @return returns the race of this Unit
         * \see CreatureTypeFlags
         * \see Races
         */
        uint8 getRace() const { return GetByteValue(UNIT_FIELD_BYTES_0, 0); }
        /**
         * Returns a bitmask representation of the current race given by Races, not to be
         * confused with the Creature type or such
         * @return the racemask for the current race
         * \see CreatureTypeFlags
         * \see Races
         */
        uint32 getRaceMask() const { return 1 << (getRace() - 1); }
        /**
         * Returns the class of this Unit
         * @return the class of the Unit
         * \see Classes
         */
        uint8 getClass() const { return GetByteValue(UNIT_FIELD_BYTES_0, 1); }
        /**
         * Returns a bitmask representation of the current class given by Classes
         * @return the classmask for the class
         * \see Classes
         */
        uint32 getClassMask() const { return 1 << (getClass() - 1); }
        /**
         * Gives you the current gender of this Unit
         * @return The current gender
         * \see Gender
         */
        uint8 getGender() const { return GetByteValue(UNIT_FIELD_BYTES_0, 2); }

        /**
         * Gets a stat for the current Unit
         * @param stat The stat you want to get, ie: Stats::STAT_STRENGTH
         * @return the value the given stat has
         * \see Stats
         */
        float GetStat(Stats stat) const { return float(GetUInt32Value(UNIT_FIELD_STAT0 + stat)); }
        /**
         * Sets a stat for this Unit
         * @param stat the stat to change
         * @param val the value to change it to
         * \see Stats
         */
        void SetStat(Stats stat, int32 val) { SetStatInt32Value(UNIT_FIELD_STAT0 + stat, val); }
        /**
         * Gets the armor for this Unit
         * @return the current armor
         * \see SpellSchools
         */
        uint32 GetArmor() const { return GetResistance(SPELL_SCHOOL_NORMAL) ; }
        /**
         * Sets the armor for this Unit
         * @param val the value to set the armor to
         * \see SpellSchools
         */
        void SetArmor(int32 val) { SetResistance(SPELL_SCHOOL_NORMAL, val); }

        /**
         * Gets the resistance against a certain spell school, ie: fire, frost, nature etc
         * @param school the type of resistance you want to get
         * @return the current resistance against the given school
         */
        uint32 GetResistance(SpellSchools school) const { return GetUInt32Value(UNIT_FIELD_RESISTANCES + school); }
        /**
         * Sets a resistance for this Unit
         * @param school the type of resistance you want to set
         * @param val the value to set it to
         */
        void SetResistance(SpellSchools school, int32 val) { SetStatInt32Value(UNIT_FIELD_RESISTANCES + school, val); }

        /**
         * Gets the health of this Unit
         * @return the current health for this unit
         * \see EUnitFields
         * \see GetUInt32Value
         */
        uint32 GetHealth()    const { return GetUInt32Value(UNIT_FIELD_HEALTH); }
        /**
         * Gets the maximum health of this Unit
         * @return the max health this Unit can have
         * \see EUnitFields
         * \see GetUInt32Value
         */
        bool HealthAbovePctHealed(int32 pct, uint32 heal) const { return uint64(GetHealth()) + uint64(heal) > CountPctFromMaxHealth(pct); }
        uint32 GetMaxHealth() const { return GetUInt32Value(UNIT_FIELD_MAXHEALTH); }
        bool IsFullHealth() const { return GetHealth() == GetMaxHealth(); }
        bool HealthBelowPct(int32 pct) const { return GetHealth() < CountPctFromMaxHealth(pct); }
        bool HealthBelowPctDamaged(int32 pct, uint32 damage) const { return int64(GetHealth()) - int64(damage) < int64(CountPctFromMaxHealth(pct)); }
        bool HealthAbovePct(int32 pct) const { return GetHealth() > CountPctFromMaxHealth(pct); }
        /**
         * Gets the percent of the health. The formula: (GetHealth() * 100) / GetMaxHealth()
         * @return the current percent of the health
         * \see GetHealth
         * \see GetMaxHealth
         */
        float GetHealthPercent() const { return (GetHealth() * 100.0f) / GetMaxHealth(); }
        uint32 CountPctFromMaxHealth(int32 pct) const { return (GetMaxHealth() * static_cast<float>(pct) / 100.0f); }
        uint32 CountPctFromCurHealth(int32 pct) const { return (GetHealth() * static_cast<float>(pct) / 100.0f); }
        /**
         * Sets the health to the given value, it cant be higher than Unit::GetMaxHealth though
         * @param val the value to set the health to
         */
        void SetHealth(uint32 val);
        /**
         * Sets the max health for this Unit, also makes sure to update the party with the new
         * value
         * @param val the new max value for the health
         * \see SetHealth
         * \see GetMaxHealth
         */
        void SetMaxHealth(uint32 val);
        /**
         * Sets the health to a certain percentage
         * @param percent the new percent to change it to, ie: 50.0f, not 0.5f for 50%
         */
        void SetHealthPercent(float percent);
        /**
         * Modifies the health by the difference given. If the character had 100 health and we sent in
         * -150 as the amount to decrease it would return -100 as that is how much it decreased since
         * we cant be under 0 health.
         * @param val the difference to apply to the health, ie: -100 would decrease the life by 100
         * @return how much the Unit gained/lost in health.
         */
        int32 ModifyHealth(int32 val);

        /**
         * Gets the power type for this Unit
         * @return The type of power this Unit uses
         */
        Powers GetPowerType() const { return Powers(GetByteValue(UNIT_FIELD_BYTES_0, 3)); }
        void SetPowerType(Powers power);
        uint32 GetPower(Powers power) const { return GetUInt32Value(UNIT_FIELD_POWER1 + power); }
        uint32 GetMaxPower(Powers power) const { return GetUInt32Value(UNIT_FIELD_MAXPOWER1 + power); }
        void SetPower(Powers power, uint32 val);
        void SetMaxPower(Powers power, uint32 val);
        int32 ModifyPower(Powers power, int32 val);
        /**
         * Mods a power by increasing or decreasing it's value
         * @param power which power to mod
         * @param val how much to increase/decrease the given power
         * @param apply whether to apply or remove the mod
         * \see ApplyModUInt32Value
         */
        void ApplyPowerMod(Powers power, uint32 val, bool apply);
        /**
         * Changes the possible max value of the given Powers power.
         * @param power increase max for this power
         * @param val what to add/remove to/from the current max
         * @param apply whether to apply it or remove it
         * \see ApplyModUInt32Value
         */
        void ApplyMaxPowerMod(Powers power, uint32 val, bool apply);

        /**
         * Gets the attack time until next attack for the given weapon type
         * @param att what attack type we want to get attacktime for
         * @return the current attack time, which takes mods of attack speed into account
         * \see Unit::m_modAttackSpeedPct
         * \see EUnitFields
         * \todo Is the time returned in seconds
         */
        uint32 GetAttackTime(WeaponAttackType att) const { return (uint32)(GetFloatValue(UNIT_FIELD_BASEATTACKTIME + att) / m_modAttackSpeedPct[att]); }
        /**
         * Changes the attack time for a certain weapon type.
         * @param att what attack type we want to change the time for
         * @param val what to set it to
         * \see Unit::m_modAttackSpeedPct
         * \see EUnitFields
         */
        void SetAttackTime(WeaponAttackType att, uint32 val) { SetFloatValue(UNIT_FIELD_BASEATTACKTIME + att, val * m_modAttackSpeedPct[att]); }
        /**
         * Applies a percentage change to a given attack type
         * @param att attack type to mod
         * @param val how many percent to add/remove, ie: 90.0f = 90%
         * @param apply whether to add or remove the effect/mod
         * \see ApplyPercentModFloatVar
         * \see ApplyPercentModFloatValue
         */
        void ApplyAttackTimePercentMod(WeaponAttackType att, float val, bool apply);
        /**
         * Same as ApplyAttackTimePercentMod but for the casting time of spells
         * instead.
         * @param val how many percent to add/remove, ie: 90.0f = 90%
         * @param apply whether to add or remove the effect/mod
         * \see Unit::ApplyAttackTimePercentMod
         */
        void ApplyCastTimePercentMod(float val, bool apply);

        /**
         * Gets the current sheath state, it is whether your main-weapon, ranged-weapon or no
         * weapon is being shown in your hands
         * @return The current sheath state
         */
        SheathState GetSheath() const { return SheathState(GetByteValue(UNIT_FIELD_BYTES_2, 0)); }
        /**
         * Changes the current sheath state.
         * @param sheathed The new weapon or none of them to show
         * \see Unit::GetSheath
         */
        virtual void SetSheath(SheathState sheathed) { SetByteValue(UNIT_FIELD_BYTES_2, 0, sheathed); }

        /**
         * Gets the faction that this unit currently belongs to, also
         * called faction template id it seems. More data probably to
         * be found in the DBC files.
         * @return The faction this unit belongs to
         * \see EUnitFields
         * \todo Does this link correctly to the EUnitFields?
         * \see EUnitFields::UNIT_FIELD_FACTIONTEMPLATE
         * \see FactionTemplateEntry
         * \see FactionEntry
         */
        uint32 getFaction() const { return GetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE); }
        /**
         * Changes the faction a unit belongs to.
         * @param faction Faction to change to
         * \see EUnitFields
         * \todo Does this link correctly to the EUnitFields?
         * \see EUnitFields::UNIT_FIELD_FACTIONTEMPLATE
         * \see FactionTemplateEntry
         * \see FactionEntry
         */
        void setFaction(uint32 faction) { SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, faction); }
        FactionTemplateEntry const* getFactionTemplateEntry() const;
        /**
         * Are we hostile towards the given Unit?
         * @param unit the unit we want to check against
         * @return true if the Unit is considered hostile, false otherwise
         */
        bool IsHostileTo(Unit const* unit) const override;
        /**
         * Is this Unit hostile towards players?
         * @return true if the Unit is hostile towards players, false otherwise
         */
        bool IsHostileToPlayers() const;
        /**
         * Is this Unit friendly towards the given Unit?
         * @param unit the Unit to check against
         * @return true if the Unit is considered friendly to us, false otherwise
         */
        bool IsFriendlyTo(Unit const* unit) const override;
        /**
         * Is this Unit neutral to everyone?
         * @return True if considered neutral to everyone, false otherwise.
         */
        bool IsNeutralToAll() const;
        /**
         * Check if this Unit is a guardian of a contested territory, this is
         * useful when we want to know if we should attack all players or only
         * players not belonging to our "side" ally/horde.
         * @return true if this Unit is a guard in a contested area, false otherwise
         */
        bool IsContestedGuard() const
        {
            if (FactionTemplateEntry const* entry = getFactionTemplateEntry())
            {
                return entry->IsContestedGuardFaction();
            }

            return false;
        }
        /**
         * Is PVP enabled?
         * @return true if this Unit is eligible for PVP fighting
         */
        bool IsPvP() const { return HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP); }
        /**
         * Put the Unit into our out of PVP
         * @param state true if we want to set PVP on, false otherwise
         */
        void SetPvP(bool state);
        /**
         * Returns the CreatureType for this Unit. For players this most often is
         * CREATURE_TYPE_HUMANOID unless he/she has shapeshifted or something like that.
         * Ie: Bear form probably wouldn't yield the same return value.
         * For creatures though Creature::GetCreatureInfo() is called and the CreatureInfo::type
         * field is used.
         * @return the CreatureType for this Unit
         * \see CreatureType
         */
        uint32 GetCreatureType() const;
        /**
         * Returns a bitmask representation of CreatureType for this Unit.
         * @return A bitmask representation of GetCreatureType()
         */
        uint32 GetCreatureTypeMask() const
        {
            uint32 creatureType = GetCreatureType();
            return (creatureType >= 1) ? (1 << (creatureType - 1)) : 0;
        }

        bool isVendor()       const { return HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_VENDOR); }
        bool isTrainer()      const { return HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_TRAINER); }
        bool isQuestGiver()   const { return HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER); }
        bool isGossip()       const { return HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); }
        bool isTaxi()         const { return HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_FLIGHTMASTER); }
        bool isGuildMaster()  const { return HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_PETITIONER); }
        bool isBattleMaster() const { return HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_BATTLEMASTER); }
        bool isBanker()       const { return HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_BANKER); }
        bool isInnkeeper()    const { return HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_INNKEEPER); }
        bool isSpiritHealer() const { return HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPIRITHEALER); }
        bool isSpiritGuide()  const { return HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPIRITGUIDE); }
        bool isTabardDesigner()const { return HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_TABARDDESIGNER); }
        bool isArmorer()      const { return HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_REPAIR); }
        bool isServiceProvider() const
        {
            return HasFlag(UNIT_NPC_FLAGS,
                UNIT_NPC_FLAG_VENDOR | UNIT_NPC_FLAG_TRAINER | UNIT_NPC_FLAG_FLIGHTMASTER |
                UNIT_NPC_FLAG_PETITIONER | UNIT_NPC_FLAG_BATTLEMASTER | UNIT_NPC_FLAG_BANKER |
                UNIT_NPC_FLAG_INNKEEPER | UNIT_NPC_FLAG_SPIRITHEALER |
                UNIT_NPC_FLAG_SPIRITGUIDE | UNIT_NPC_FLAG_TABARDDESIGNER | UNIT_NPC_FLAG_AUCTIONEER);
        }
        bool isSpiritService() const { return HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPIRITHEALER | UNIT_NPC_FLAG_SPIRITGUIDE); }

        /**
         * Gets the current stand state for this Unit as described by UnitStandStateType.
         * @return The current stand state
         * \see UnitStandStateType
         * \see MAX_UNIT_STAND_STATE
         */
        uint8 getStandState() const { return GetByteValue(UNIT_FIELD_BYTES_1, 0); }
        /**
         * Is this Unit sitting down in some way?
         * @return true if the Unit is sitting down, false otherwise
         */
        bool IsSitState() const;
        /**
         * Is this Unit just standing normally? This method will return false
         * even if you would consider the state as standing, ie: when the Unit
         * has the state UNIT_STAND_STATE_SLEEP it is considered not standing.
         * @return true if the Unit is standing normally, false otherwise
         */
        bool IsStandState() const;

        bool IsSeatedState() const;
        /**
         * Change the stand state for this Unit. For possible values check
         * UnitStandStateType.
         * @param state
         * \see UnitStandStateType
         */
        void SetStandState(uint8 state);

        /**
         * Is this Unit mounted?
         * @return true if it's mounted, false otherwise
         * \see EUnitFields
         */
        bool IsMounted() const { return GetMountID(); }
        /**
         * Gets the currently used mount id.
         * @return id of the currently used mount
         */
        uint32 GetMountID() const { return GetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID); }
        /**
         * Mounts this Unit by setting the UNIT_FIELD_MOUNTDISPLAYID to the given mount
         * id and setting the bitflag UNIT_FLAG_MOUNT in UNIT_FIELD_FLAGS. If this Unit
         * is a player pets and such are despawned or not depending on the config option
         * CONFIG_BOOL_PET_UNSUMMON_AT_MOUNT.
         * @param mount the id of the mount to mount
         * @param spellId id of the spell used to summon the mount, if 0 is passed in this is treated
         * as a GM command or the Taxi service mounting the Player.
         */
        virtual void Mount(uint32 mount, uint32 spellId = 0);
        /**
         * Unmounts this Unit by sending the SMSG_DISMOUNT to the client if it was a dismount
         * not issued by a GM / the Taxi service. Also changes the UNIT_FIELD_MOUNTDISPLAYID
         * back to 0 and removes the flag UNIT_FLAG_MOUNT from UNIT_FIELD_FLAGS.
         * @param from_aura if this was true the Unit was probably interrupted by a spell
         * or something hitting it forcing a dismount.
         */
        virtual void Unmount(bool from_aura = false);

        /**
         * Returns the maximum skill value the given Unit can have. Ie: the sword skill can
         * be maxed to 300 at level 60. And when you start a level 1 character you maximum
         * skill with swords (given that you know them) is 5. The formula used is:
         * Current Level * 5
         * @param target target to get maximum skill value for, if this is NULL the
         * returned value is for ourselves.
         * @return the maximum skill level you can have at the your current level.
         * \todo Check out the GetLevelForTarget as it seems it's not doing anything constructive with it's arguments.
         */
        uint16 GetMaxSkillValueForLevel(Unit const* target = NULL) const { return (target ? GetLevelForTarget(target) : getLevel()) * 5; }
        /**
         * Deals damage mods to the given victim. If the victim is dead, flying or in evade
         * mode (for creatures) then the damage is absorbed into absorb and no damage
         * is done.
         * @param pVictim
         * @param damage how much damage we want to try to make, will be updated to how
         * much was actually made
         * @param absorb if this is != NULL it will be updated with how much more from
         * before of the damage that was absorbed. ie: absorb += damage not done
         * \todo Does DamageDeal in the AI's do anything?
         * \todo Fix this comment, doesn't really seem correct.
         */
        void DealDamageMods(Unit* pVictim, uint32& damage, uint32* absorb);
        /**
         * Generally deals damage to a Unit.
         * @param pVictim victim that will take damage
         * @param damage the damage to make
         * @param cleanDamage melee damage to make
         * @param damagetype the type of damage we'll be doing, ie: DOT, DIRECT_DAMAGE etc.
         * @param damageSchoolMask what school the damage has
         * @param spellProto prototype for the spell that was cast
         * @param durabilityLoss whether this damage should give a durability loss (10%) on death
         * or not
         * @return probably how much damage was actually dealt?
         * \todo Cleanup this function and split into smaller functions for readability
         */
        uint32 DealDamage(Unit* pVictim, uint32 damage, CleanDamage const* cleanDamage, DamageEffectType damagetype, SpellSchoolMask damageSchoolMask, SpellEntry const* spellProto, bool durabilityLoss);
        /**
         * Generally heals a target for addhealth health
         * @param pVictim the victim to heal
         * @param addhealth how much health to add, modified by Unit::ModifyHealth
         * @param spellProto spell prototype for the spell that made this heal
         * @param critical whether or not this was a critical heal (true => crit)
         * @return how much the target actually gained in health
         */
        int32 DealHeal(Unit* pVictim, uint32 addhealth, SpellEntry const* spellProto, bool critical = false);

        /**
         * Calls CallForAllControlledUnits with CONTROLLED_MINIPET and CONTROLLED_GUARDIAN
         * to make them do something if they should when their owner kills someone/thing
         * @param pVictim the target that was killed
         * \see CallForAllControlledUnits
         * \see ControlledUnitMask
         */
        void PetOwnerKilledUnit(Unit* pVictim);

        /**
         * Hard to figure out what this does.
         * \todo Document this.
         * @param pVictim possible victim of the proc
         * @param procAttacker
         * @param procVictim
         * @param procEx
         * @param amount
         * @param attType
         * @param procSpell
         * \see ProcFlagsEx
         */
        void ProcDamageAndSpell(Unit* pVictim, uint32 procAttacker, uint32 procVictim, uint32 procEx, uint32 amount, WeaponAttackType attType = BASE_ATTACK, SpellEntry const* procSpell = NULL);
        /**
         * Same as for Unit::ProcDamageAndSpell
         * @param isVictim whether the target is considered the victim or not
         * @param pTarget
         * @param procFlag
         * @param procExtra
         * @param attType
         * @param procSpell
         * @param damage
         * \see ProcFlagsEx
         */
        void ProcDamageAndSpellFor(bool isVictim, Unit* pTarget, uint32 procFlag, uint32 procExtra, WeaponAttackType attType, SpellEntry const* procSpell, uint32 damage);

        /**
         * Handles an emote, for example /charge would write something
         * along the lines: "NAME begins to charge" in orange text. This
         * method checks if it's a command or state, a command usually doesn't
         * show anything while a state would show something, ie stand
         * the character up.
         * @param emote_id id of the emote to handle
         * \see EmotesEntry
         * \todo Is this accurate?
         */
        void HandleEmote(uint32 emote_id);                  // auto-select command/state
        /**
         * Sends a packet to the client SMSG_CLIENT with the emote_id given
         * which in turn probably makes the client show some sort of animation
         * for the given emote_id
         * @param emote_id id of the emote to show
         */
        void HandleEmoteCommand(uint32 emote_id);
        /**
         * Just updates the UNIT_NPC_EMOTESTATE field to the given emote_id.
         * @param emote_id the emote to show
         */
        void HandleEmoteState(uint32 emote_id);
        /**
         * Seems to do some damage to pVictim and also does extra attacks if the Unit
         * has any by recursively calling itself up to Unit::m_extraAttacks times with
         * the extra parameter set to true instead of the default false.
         *
         * Also calculates melee damage using Unit::CalculateMeleeDamage, deals damage and
         * such using Unit::DealDamageMods and also procs any spell that might be interesting
         * (TODO: Is that actually what ProcDamageAndSpell does?) using Unit::ProcDamageAndSpell
         *
         * @param pVictim the victim to hit
         * @param attType what hand (main/off) we were using
         * @param extra whether this was called recursively as an extra attack (true) or not (false)
         */
        void AttackerStateUpdate(Unit* pVictim, WeaponAttackType attType = BASE_ATTACK, bool extra = false);

        /**
         * Calculates the chance that a melee attack will miss the given victim.
         * The cap for miss chance is 0-60%, ie: you can't have a higher miss chance
         * than 60% and not lower than 0%.
         * @param pVictim the victim that will be attacked
         * @param attType type of attack
         * @return percentage between 0-60, ie: 57.0f = 57%
         */
        float MeleeMissChanceCalc(const Unit* pVictim, WeaponAttackType attType) const;

        /**
         * Fills the CalcDamageInfo structure with data about how much damage was done, in what way,
         * how much was absorbed etc. Also checks for different procs and inserts these flags into
         * the structure. Also calculates bonus damage with Unit::MeleeDamageBonusDone and the damage
         * with Unit::CalculateDamage
         * @param pVictim the victim that was hit with damage
         * @param damage how much damage to try to do
         * @param damageInfo this is filled with data about what kind of damage that was done
         * @param attackType type of attack, base/off/ranged
         */
        void CalculateMeleeDamage(Unit* pVictim, CalcDamageInfo* damageInfo, WeaponAttackType attackType = BASE_ATTACK);
        /**
         * Deals melee damage, if the attack was parried we reduce the victims time until next hit
         * instead of the weapons normal time by 20 or 60%.
         * Also, if this is a NPC behind a (usually fleeing) player we have a chance to daze the
         * target. Will update the Judgement aura duration too, and check if the victim given from
         * CalcDamageInfo has any shields up and do damage to them in that case.
         * @param damageInfo used to deal the damage
         * @param durabilityLoss whether or not durability loss should happen
         */
        void DealMeleeDamage(CalcDamageInfo* damageInfo, bool durabilityLoss);
        /**
        * Handles all extra attacks set up by a spell
        */
        void HandleProcExtraAttackFor(Unit* victim);
        /**
         * Calculates how much damage a spell should do, it will do some bonus damage according
         * to which SpellNonMeleeDamage::DmgClass it belongs to, ie: SPELL_DAMAGE_CLASS_RANGED
         * or SPELL_DAMAGE_CLASS_MELEE does bonus melee damage while the others make bonus spell
         * damage. Also reduces the damage done based on armor.
         * After returning this function will have filled the SpellNoneMeleeDamage::damage with
         * how much damage was actually done.
         * @param damageInfo info about attacker, target etc
         * @param damage how much damage to try to do
         * @param spellInfo info about the spell, needed by the helper functions
         * @param attackType what we were attacking with
         * \see Unit::IsSpellCrit
         * \see Unit::CalcArmorReducedDamage
         * \see SpellDmgClass
         */
        void CalculateSpellDamage(SpellNonMeleeDamage* damageInfo, int32 damage, SpellEntry const* spellInfo, WeaponAttackType attackType = BASE_ATTACK);
        /**
         * Deals actual damage based on info given. Does some checking if the spell actually exists
         * and updates the Judgement aura duration if it's there. Then it calls the DealDamage with
         * a SPELL_DIRECT_DAMAGE instead of DIRECT_DAMAGE to indicate that it was caused by a spell
         * (might be more than just that though)
         * @param damageInfo contains info about what kind of damage we will do etc
         * @param durabilityLoss whether or not durability loss should happen
         */
        void DealSpellDamage(SpellNonMeleeDamage* damageInfo, bool durabilityLoss);

        /**
         * Calculates the miss chance for a melee spell (a melee spell could be Sinister Strike).
         * Does this by first calculating the hit chance and then "inversing" that value, ie:
         * 100 - hitchance = misschance. The hit chance can be changed by the aura modifiers
         * SPELL_AURA_MOD_ATTACKER_RANGED_HIT_CHANCE for ranged and by
         * SPELL_AURA_MOD_ATTACKER_MELEE_HIT_CHANCE for melee attacks.
         * You can also resist miss chance with the spell mod SPELLMOD_RESIST_MISS_CHANCE
         * @param pVictim the victim of the attack
         * @param attType main/off hand attack
         * @param skillDiff the skill difference between attackers weapon skill and the victims defense skill, ie: attacker weapon skill - victim defense skill, the lesser this diff is the higher the chance to hit and the lower the chance to miss
         * @param spell what spell was cast
         *
         * @return a value between 0.0f and 60.0f indicating a 0% - 60% miss chance
         * \see Player::ApplySpellMod
         * \see Unit::GetTotalAuraModifier
         * \see Unit::GetSpellModOwner
         */
        float  MeleeSpellMissChance(Unit* pVictim, WeaponAttackType attType, int32 skillDiff, SpellEntry const* spell);
        /**
         * Tells what happened with the spell that was cast, some spells can't miss and they
         * have the attribute SPELL_ATTR_EX3_CANT_MISS. Also, in PvP you can't dodge or parry
         * when the attacker is behind you, but this is possible in PvE.
         *
         * Creatures with the flag CREATURE_FLAG_EXTRA_NO_PARRY can't parry an attack
         * @param pVictim the victim that was hit
         * @param spell the spell that was cast
         * @return Whether or not the spell hit/was resisted/blocked etc. A successfull cast would result in SPELL_MISS_NONE being returned
         * \see SpellEntry::HasAttribute for checking the SPELL_ATTR_EX3_CANT_MISS
         * \see Creature::GetCreatureInfo for the flags_extra
         */
        SpellMissInfo MeleeSpellHitResult(Unit* pVictim, SpellEntry const* spell);
        /**
         * This works pretty much like MeleeSpellHitResult but for magic spells instead.
         * For AOE spells there's a \ref Modifier called \ref AuraType::SPELL_AURA_MOD_AOE_AVOIDANCE
         * that reduces the spells hit chance.
         * @param pVictim the victim that was hit
         * @param spell the spell that was cast
         * @return Whether or not the spell was resisted/blocked etc. Seems the only 2
         * possible values are \ref SpellMissInfo::SPELL_MISS_RESIST or
         * \ref SpellMissInfo::SPELL_MISS_NONE
         * \todo Need use unit spell resistance in calculations (Old comment)
         */
        SpellMissInfo MagicSpellHitResult(Unit* pVictim, SpellEntry const* spell);
        /**
         * This combined \ref Unit::MagicSpellHitResult and \ref Unit::MeleeSpellHitResult and also
         * does checks for if the victim is immune or if it is in evade mode etc. If it's a positive
         * spell it can't miss either. Also takes care of reflects via PROC_EX_REFLECT and removes
         * possible charges that could have been present for reflecting spells. Lastly calls one
         * of the earlier mentioned functions depending on the SpellEntry::DmgClass.
         * Calculate spell hit result can be:
         * Every spell can: Evade/Immune/Reflect/Sucesful hit
         * For melee based spells:
         *   Miss
         *   Dodge
         *   Parry
         * For spells
         *   Resist
         * @param pVictim the victim that was hit
         * @param spell the spell that was cast
         * @param canReflect whether or not this spell can be reflected
         * @return Whether or not the spell was resisted/blocked etc.
         */
        SpellMissInfo SpellHitResult(Unit* pVictim, SpellEntry const* spell, bool canReflect = false);

        /**
         * Returns the units dodge chance
         * @return Units dodge chance in percent as value between 0.0f - 100.0f representing 0% - 100%
         */
        float GetUnitDodgeChance()    const;
        /**
         * Returns the units parry chance
         * @return Units parry chance in percent as value between 0.0f - 100.0f representing 0% - 100%
         */
        float GetUnitParryChance()    const;
        /**
         * Returns the units block chance
         * @return Units block chance in percent as value between 0.0f - 100.0f representing 0% - 100%
         */
        float GetUnitBlockChance()    const;
        /**
         * Returns the units critical hit chance against the given target as a value between
         * 0.0f - 100.0f representing 0% - 100%. Aura modifiers named
         * SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_CHANCE and SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_CHANCE
         * can increase the critical hit chance. Also the skill level in defense for the target
         * may increase it by formula: (Our max skill - target defense skill) * 0.04
         * @param attackType weapon we will attack with
         * @param pVictim the victim we want to calculate against
         * @return Units critical hit chance in percent as value between 0.0f - 100.0f representing 0% - 100%
         */
        float GetUnitCriticalChance(WeaponAttackType attackType, const Unit* pVictim) const;

        /**
         * Gets how much the shield would block via \ref Unit::m_auraBaseMod and \ref Unit::GetStat
         * for \ref STAT_STRENGTH. Seems to be implemented only in Player.cpp
         * @return Currently equipped shield block value
         */
        virtual uint32 GetShieldBlockValue() const = 0;
        /**
         * The melee skill for the given Unit. For units this is always their maximum possible
         * for their level, ie: current level * 5, for level 60 this would give a skill of 300
         * @param target the target to find the max skill for, if it's NULL we find the level for us
         * @return The max skill level for the given Unit
         */
        uint32 GetUnitMeleeSkill(Unit const* target = NULL) const { return (target ? GetLevelForTarget(target) : getLevel()) * 5; }
        /**
         * Gets the defense skill for the given target, if the target is a Player and this Unit
         * is a Player the maximum skill for that level is used for balancing. If this Unit isn't
         * a Player we fall back to \ref Unit::GetUnitMeleeSkill for the given target.
         * @param target the target we would like to find our skill value against if any
         * @return The skill value for our defense if a target is sent and both are Players, otherwise
         * skill value for the given target.
         * \todo Is the logic for the return correct in here?
         */
        uint32 GetDefenseSkillValue(Unit const* target = NULL) const;
        /**
         * Get's the skill value for the given weapon type. The same idea as for
         * \ref Unit::GetDefenseSkillValue applies, if both target and this are Players
         * we use the max skill instead of actual skill.
         * @param attType the weapon type we want to find the skill for
         * @param target our target if any, if both are Players this will change outcome of skill
         * @return The skill value that the Unit holds in the given hand via attackType
         * \see Item::GetSkill
         * \see SkillType
         */
        uint32 GetWeaponSkillValue(WeaponAttackType attType, Unit const* target = NULL) const;
        /**
         * Returns the proc chance for one weapon, if the \ref BASE_ATTACK is ready then the
         * proc chance for that is returned, otherwise if the \ref OFF_ATTACK is ready and
         * there's a weapon equipped there that chance will be returned, otherwise 0.
         *
         * The formula used for calculation is rather interesting:
         * Mainhand: GetAttackTime(BASE_ATTACK) * 1.8f / 1000.0f
         * Offhand: GetAttackTime(OFF_ATTACK) * 1.6f / 1000.0f
         * @return first the main weapons proc chance, then the off weapons proc chance.
         * \see GetAttackTime
         * \see isAttackReady
         * \todo Add code tags to the formulas
         */
        float GetWeaponProcChance() const;
        /**
         * This returns the proc per minute chance as a percentage.
         * Comment from cpp file:
         * result is chance in percents (probability = Speed_in_sec * (PPM / 60))
         * @param WeaponSpeed the weapon speed, usually gotten with \ref GetAttackTime
         * @param PPM the proc per minute rate
         * @return the chance for a proc in percent (taken from cpp file)
         * \todo What does this actually do? How/Where is it used?
         */
        float GetPPMProcChance(uint32 WeaponSpeed, float PPM) const;

        /**
         * This acts as a wrapper for \ref Unit::RollMeleeOutcomeAgainst with more parameters,
         * these are initialised from the pVictim using
         *  - \ref Unit::MeleeMissChanceCalc
         *  - \ref Unit::GetUnitCriticalChance
         *  - \ref Unit::GetUnitDodgeChance
         *  - \ref Unit::GetUnitBlockChance
         *  - \ref Unit::GetUnitParryChance
         * @param pVictim the victim to target
         * @param attType with what "hand" you want to attack
         * @return what the hit resulted in, miss/hit etc.
         */
        MeleeHitOutcome RollMeleeOutcomeAgainst(const Unit* pVictim, WeaponAttackType attType) const;
        /**
         * Calculates what off a few possible things that can happen when a victim is attacked
         * with melee weapons. For a list of the things that could happen see \ref MeleeHitOutcome.
         * There's a few formulas involved here, for more info on them check the cpp file. But as
         * usual, if you're behind your victim they can't parry/block and players can't dodge while
         * mobs can.
         * @param pVictim the victim of the attack
         * @param attType the had to attack with
         * @param crit_chance crit chance against victim
         * @param miss_chance miss chance against victim
         * @param dodge_chance victims dodge chance
         * @param parry_chance victims parry chance
         * @param block_chance victims block chance
         * @param SpellCasted whether or not this was because of a spell of autoattack (false => autoattack)
         * @return what the hit resulted in, miss/hit etc
         */
        MeleeHitOutcome RollMeleeOutcomeAgainst(const Unit* pVictim, WeaponAttackType attType, int32 crit_chance, int32 miss_chance, int32 dodge_chance, int32 parry_chance, int32 block_chance, bool SpellCasted) const;

        /**
         * @return true if this unit is a vendor, false otherwise
         * \see Object::HasFlag
         * \see EUnitFields
         * \see NPCFlags
         */
        bool IsVendor()       const { return HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_VENDOR); }
        /**
         * @return true if this unit is a trainer, false otherwise
         * \see Object::HasFlag
         * \see EUnitFields
         * \see NPCFlags
         */
        bool IsTrainer()      const { return HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_TRAINER); }
        /**
         * @return true if this unit is a QuestGiver, false otherwise
         * \see Object::HasFlag
         * \see EUnitFields
         * \see NPCFlags
         */
        bool IsQuestGiver()   const { return HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER); }
        /**
         * @return true if this unit is a gossip, false otherwise
         * \see Object::HasFlag
         * \see EUnitFields
         * \see NPCFlags
         */
        bool IsGossip()       const { return HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); }
        /**
         * @return true if this unit is a taxi, false otherwise
         * \see Object::HasFlag
         * \see EUnitFields
         * \see NPCFlags
         */
        bool IsTaxi()         const { return HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_FLIGHTMASTER); }
        /**
         * @return true if this unit is a GuildMaster, false otherwise
         * \see Object::HasFlag
         * \see EUnitFields
         * \see NPCFlags
         */
        bool IsGuildMaster()  const { return HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_PETITIONER); }
        /**
         * @return true if this unit is a BattleMaster, false otherwise
         * \see Object::HasFlag
         * \see EUnitFields
         * \see NPCFlags
         */
        bool IsBattleMaster() const { return HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_BATTLEMASTER); }
        /**
         * @return true if this unit is a banker, false otherwise
         * \see Object::HasFlag
         * \see EUnitFields
         * \see NPCFlags
         */
        bool IsBanker()       const { return HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_BANKER); }
        /**
         * @return true if this unit is a innkeeper, false otherwise
         * \see Object::HasFlag
         * \see EUnitFields
         * \see NPCFlags
         */
        bool IsInnkeeper()    const { return HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_INNKEEPER); }
        /**
         * @return true if this unit is a SpiritHealer, false otherwise
         * \see Object::HasFlag
         * \see EUnitFields
         * \see NPCFlags
         */
        bool IsSpiritHealer() const { return HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPIRITHEALER); }
        /**
         * @return true if this unit is a SpiritGuide, false otherwise
         * \see Object::HasFlag
         * \see EUnitFields
         * \see NPCFlags
         */
        bool IsSpiritGuide()  const { return HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPIRITGUIDE); }
        /**
         * @return true if this unit is a TabardDesigner, false otherwise
         * \see Object::HasFlag
         * \see EUnitFields
         * \see NPCFlags
         */
        bool IsTabardDesigner()const { return HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_TABARDDESIGNER); }
        /**
         * @return true if this unit is a Auctioneer, false otherwise
         * \see Object::HasFlag
         * \see EUnitFields
         * \see NPCFlags
         */
        bool isAuctioner()    const { return HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_AUCTIONEER); }
        /**
         * @return true if this unit is a armorer, false otherwise
         * \see Object::HasFlag
         * \see EUnitFields
         * \see NPCFlags
         */
        bool IsArmorer()      const { return HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_REPAIR); }
        /**
         * Returns if this is a service provider or not, a service provider has one of the
         * following flags:
         * - \ref UNIT_NPC_FLAG_VENDOR
         * - \ref UNIT_NPC_FLAG_TRAINER
         * - \ref UNIT_NPC_FLAG_FLIGHTMASTER
         * - \ref UNIT_NPC_FLAG_PETITIONER
         * - \ref UNIT_NPC_FLAG_BATTLEMASTER
         * - \ref UNIT_NPC_FLAG_BANKER
         * - \ref UNIT_NPC_FLAG_INNKEEPER
         * - \ref UNIT_NPC_FLAG_SPIRITHEALER
         * - \ref UNIT_NPC_FLAG_SPIRITGUIDE
         * - \ref UNIT_NPC_FLAG_TABARDDESIGNER
         * - \ref UNIT_NPC_FLAG_AUCTIONEER
         *
         * @return true if this unit is a ServiceProvider, false otherwise
         * \see Object::HasFlag
         * \see EUnitFields
         * \see NPCFlags
         */
        bool IsServiceProvider() const
        {
            return HasFlag(UNIT_NPC_FLAGS,
                           UNIT_NPC_FLAG_VENDOR | UNIT_NPC_FLAG_TRAINER | UNIT_NPC_FLAG_FLIGHTMASTER |
                           UNIT_NPC_FLAG_PETITIONER | UNIT_NPC_FLAG_BATTLEMASTER | UNIT_NPC_FLAG_BANKER |
                           UNIT_NPC_FLAG_INNKEEPER | UNIT_NPC_FLAG_SPIRITHEALER |
                           UNIT_NPC_FLAG_SPIRITGUIDE | UNIT_NPC_FLAG_TABARDDESIGNER | UNIT_NPC_FLAG_AUCTIONEER);
        }
        /**
         * Returns if this is a spirit service or not, a spirit service has one of the
         * following flags:
         * - \ref UNIT_NPC_FLAG_SPIRITHEALER
         * - \ref UNIT_NPC_FLAG_SPIRITGUIDE
         * @return true if this unit is a spirit service, false otherwise
         * \see Object::HasFlag
         * \see EUnitFields
         * \see NPCFlags
         */
        bool IsSpiritService() const { return HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPIRITHEALER | UNIT_NPC_FLAG_SPIRITGUIDE); }

        /**
         * Is this unit flying in taxi?
         * @return true if the Unit has the state \ref UNIT_STAT_TAXI_FLIGHT (is flying in taxi), false otherwise
         * \see hasUnitState
         */
        bool IsTaxiFlying()  const { return hasUnitState(UNIT_STAT_TAXI_FLIGHT); }

        /**
         * Checks to see if a creature, whilst moving along a path, has reached a specific waypoint, or near to
         * @param currentPositionX is the creature's current X ordinate in the game world
         * @param currentPositionY is the creature's current Y ordinate in the game world
         * @param currentPositionZ is the creature's current Z ordinate in the game world
         * @param destinationPositionX is the in game ordinate that we wish to check against the creature's current X ordinate (are they the same, or very close?)
         * @param destinationPositionY is the in game ordinate that we wish to check against the creature's current Y ordinate (are they the same, or very close?)
         * @param destinationPositionZ is the in game ordinate that we wish to check against the creature's current Z ordinate (are they the same, or very close?)
         * @param distanceX is the distance from the creature's current X ordinate to the destination X ordinate
         * @param distanceY is the distance from the creature's current Y ordinate to the destination Y ordinate
         * @param distanceZ is the distance from the creature's current Z ordinate to the destination Z ordinate
         *
         */
        bool IsNearWaypoint(float currentPositionX, float currentPositionY, float currentPositionZ, float destinationPositionX, float destinationPositionY, float destinationPositionZ, float distanceX, float distanceY, float distanceZ);


        /**
         * Is this unit in combat?
         * @return true if the Unit has the flag \ref UNIT_FLAG_IN_COMBAT (is in combat), false otherwise
         * \see EUnitFields
         * \see UnitFlags
         */
        bool IsInCombat()  const { return HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT); }
        /**
         * Sets this \ref Unit into combat, if it already was this has no bigger meaning if the
         * PvP flag hasn't changed since last time it was applied.
         * @param PvP whether this was a PvP combat or not, this is important for how quick the combat flag will wear away and possibly more
         * @param enemy Our target that we are attacking, only does something if the attacked one is a creature it seems
         * \see ClearInCombat
         * \see SetInCombatWith
         */
        void SetInCombatState(bool PvP, Unit* enemy = NULL);
        void SetInDummyCombatState(bool state);
        /**
         * Sets us in combat with the given enemy, this in turn just does a few small checks for if
         * it's a duel or PvP and then calls \ref Unit::SetInCombatState with the correct value for
         * PvP and enemy
         * @param enemy the enemy that we are attacking/engaging
         * \see ClearInCombat
         * \see SetInCombatState
         */
        void SetInCombatWith(Unit* enemy);
        /**
         * Clears the combat flag for this unit using \ref Object::RemoveFlag and clears
         * the Unit state \ref UnitState::UNIT_STAT_ATTACK_PLAYER. This is not where a
         * \ref Player s PvP flags are cleared, that is handled in \ref Player::UpdateContestedPvP
         * \see EUnitFields
         */
        void ClearInCombat();
        /**
         * Probably returns how long it is until this Unit should get out of PvP combat again,
         * although not used in that sense.
         * @return the time we have left from our start of PvP combat
         * \todo Find out what this actually does/means
         */
        uint32 GetCombatTimer() const { return m_CombatTimer; }

        /**
         * Gets all \ref SpellAuraHolder s that have the same given spell_id
         * @param spell_id the spell_id to search for
         * @return 2 iterators to the range of \ref SpellAuraHolder s that were found
         */
        SpellAuraHolderBounds GetSpellAuraHolderBounds(uint32 spell_id)
        {
            return m_spellAuraHolders.equal_range(spell_id);
        }
        /**
         * Same as \ref Unit::GetSpellAuraHolderBounds
         */
        SpellAuraHolderConstBounds GetSpellAuraHolderBounds(uint32 spell_id) const
        {
            return m_spellAuraHolders.equal_range(spell_id);
        }

        /**
         * Checks if this \ref Unit has the given AuraType
         * @param auraType the type of aura to look for
         * @return true if this \ref Unit is affected by the given \ref AuraType, false otherwise
         */
        bool HasAuraType(AuraType auraType) const;
        /**
         * Checks if the given \ref SpellEntry affects the \ref AuraType in some way, this is done
         * by calling \ref Aura::isAffectedOnSpell which in turn seems to check if the spellProto
         * and the \ref Aura s own \ref SpellEntry have the same \ref SpellEntry::SpellFamilyName.
         * (The \ref Aura get's it's \ref SpellEntry by calling \ref Aura::GetSpellProto)
         * @param auraType the type of aura we want to check
         * @param spellProto the spell we want to check for affecting the aura type
         * @return true if the spell affects the given aura type, false otherwise
         * \todo Is this actually correct, also, make it more clear what it actually checks
         */
        bool HasAffectedAura(AuraType auraType, SpellEntry const* spellProto) const;
        /**
         * Checks if we have at least one \ref Aura that is associated with the given spell id
         * and \ref SpellEffectIndex.
         * @param spellId the spell id to look for
         * @param effIndex the effect index the \ref Aura should have
         * @return true if there was at least one \ref Aura associated with the id that belonged to
         * the correct \ref SpellEffectIndex, false otherwise
         */
        bool HasAura(uint32 spellId, SpellEffectIndex effIndex) const;
        /**
         * Checks if we have at least one \ref Aura that is associated with the given spell id via
         * the \ref Unit::m_spellAuraHolders multimap. Generalized version of the other
         * \ref Unit::HasAura
         * @param spellId the spell id to look for
         * @return true if there was at least one \ref Aura associated with the id, false otherwise
         */
        bool HasAura(uint32 spellId) const
        {
            return m_spellAuraHolders.find(spellId) != m_spellAuraHolders.end();
        }

        /**
         * This is overridden in \ref Player::HasSpell, \ref Creature::HasSpell and \ref Pet::HasSpell
         * @return false in this implementation
         */
        virtual bool HasSpell(uint32 /*spellID*/) const { return false; }

        /**
         * Check is this \ref Unit has a stealth modified applied
         * @return true if this \ref Unit has the \ref AuraType \ref AuraType::SPELL_AURA_MOD_STEALTH
         * applied, false otherwise
         * \see Modifier
         * \see Unit::HasAuraType
         * \see AuraType
         */
        bool HasStealthAura()      const { return HasAuraType(SPELL_AURA_MOD_STEALTH); }
        /**
         * Check if this \ref Unit has a invisibility \ref Aura modifier applied.
         * @return true if this \ref Unit has the \ref AuraType
         * \ref AuraType::SPELL_AURA_MOD_INVISIBILITY applied, false otherwise
         * \see Modifier
         * \see Unit::HasAuraType
         * \see AuraType
         */
        bool HasInvisibilityAura() const { return HasAuraType(SPELL_AURA_MOD_INVISIBILITY); }
        /**
         * Check if this \ref Unit has a fear \ref Aura modifier applied. Ie, is it feared?
         * @return true if this \ref Unit has the \ref AuraType \ref AuraType::SPELL_AURA_MOD_FEAR
         * applied, false otherwise
         * \see Modifier
         * \see Unit::HasAuraType
         * \see AuraType
         */
        bool IsFeared()  const { return HasAuraType(SPELL_AURA_MOD_FEAR); }
        /**
         * Check if this \ref Unit has a rooting \ref Aura modifier applied. Ie, is it stuck in
         * some way?
         * @return true if this \ref Unit has the \ref AuraType \ref AuraType::SPELL_AURA_MOD_ROOT
         * applied, false otherwise
         * \see Modifier
         * \see Unit::HasAuraType
         * \see AuraType
         */
        bool IsInRoots() const { return HasAuraType(SPELL_AURA_MOD_ROOT); }
        /**
         * Is this \ref Unit polymorphed?
         * @return true if this \ref Unit is polymorphed, false otherwise
         * \see GetSpellSpecific
         * \see Unit::GetTransform
         * \todo Move the implementation to .h file exactly as the earlier ones?
         */
        bool IsPolymorphed() const;

        /**
         * Check if this \ref Unit has  freezing \ref Aura modifier applied. Ie, is it
         * frozen in ground?
         * @return true if this \ref Unit has the \ref AuraType \ref AuraType::AURA_STATE_FROZEN,
         * false otherwise
         * \see Modifier
         * \see Unit::HasAuraType
         * \see AuraType
         * \todo Move the implementation to .h file exactly as the earlier ones?
         */
        bool IsFrozen() const;

        /**
         * Checks if this \ref Unit could be targeted with an attack, things that make that
         * impossible are:
         * - The \ref Unit / \ref Player is a GM
         * - The \ref Unit has the flags (\ref Object::HasFlag)
         * \ref UnitFlags::UNIT_FLAG_NON_ATTACKABLE
         * and \ref UnitFlags::UNIT_FLAG_NOT_SELECTABLE
         * - The \ref Unit has the flag (\ref Object::HasFlag)
         * \ref UnitFlags::UNIT_FLAG_OOC_NOT_ATTACKABLE, this seems to vary some though, since this
         * flag will be removed when the creature for some reason enters combat
         * - \ref Unit::IsAlive is equal to inverseAlive
         * - \ref Unit::IsInWorld is false
         * - the \ref Unit has the state (\ref Unit::hasUnitState) \ref  UnitState::UNIT_STAT_DIED
         * - the \ref Unit is flying in a taxi (\ref Unit::IsTaxiFlying)
         * @param inverseAlive This is needed for some spells which need
         * to be casted at dead targets (aoe) (Taken from source comment)
         * @return true if the target can be attacked, false otherwise
         * \see UnitState
         */
        bool IsTargetableForAttack(bool inverseAlive = false) const;
        /**
         * Simply checks if this \ref Unit has the flag (\ref Unit::HasFlag)
         * \ref UnitFlags::UNIT_FLAG_PASSIVE in \ref EUnitFields::UNIT_FIELD_FLAGS
         * @return true if the target is passive to hostile actions, false otherwise
         */
        bool isPassiveToHostile() { return HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PASSIVE); }

        /**
         * Is this \ref Unit in water?
         * @return true if the \ref Unit is in water, false otherwise
         * \see Object::GetTerrain
         * \see TerrainInfo::IsInWater
         */
        virtual bool IsInWater() const;
        /**
         * Is this \ref Unit under water?
         * @return true if the \ref Unit is under water, false otherwise
         * \see Object::GetTerrain
         * \see TerrainInfo::IsUnderWater
         */
        virtual bool IsUnderWater() const;
        /**
         * Can the given \ref Creature access this \ref Unit in some way? If this \ref Unit is in
         * water we check if the \ref Creature can swim, if so it's accessible, otherwise it's not.
         * If we're not in water the \ref Creature should be able to walk or fly and then we're
         * accessible.
         * @param c The \ref Creature to check accessibility for
         * @return true if this \ref Unit is accessible to the \ref Creature given, false otherwise
         * \todo Rename to IsInAccessablePlaceFor to follow standards?
         */
        bool isInAccessablePlaceFor(Creature const* c) const;

        /**
         * Sends a packet to the client with \ref OpcodesList::SMSG_SPELLHEALLOG which presumably
         * updates the combat log of this \ref Unit and shows some healing done and to who in it.
         *
         * For a description of the packets look see \ref OpcodesList::SMSG_SPELLHEALLOG
         * @param pVictim the victim of the healing spell
         * @param SpellID what spell id that was used
         * @param Damage how much "damage" we did (healing in this case)
         * @param critical whether it was a critical hit or not.
         * \see WorldPacket
         */
        void SendHealSpellLog(Unit* pVictim, uint32 SpellID, uint32 Damage, bool critical = false);
        /**
         * Sends a packet to the client with \ref OpcodesList::SMSG_SPELLENERGIZELOG which presumably
         * updates the combat log of this \ref Unit and shows some enery regen and to who it was.
         *
         * For a description of the packets look see \ref OpcodesList::SMSG_SPELLENERGIZELOG
         * @param pVictim the victim of the regen
         * @param SpellID the spell id that caused it
         * @param Damage how much was regenerated
         * @param powertype the power that was regenerated
         */
        void SendEnergizeSpellLog(Unit* pVictim, uint32 SpellID, uint32 Damage, Powers powertype);
        /**
         * Regenerates/degenerates the given amount of "damage" for the given power and sends a
         * update to the combat log.
         * @param pVictim the victim to add/remove power from
         * @param SpellID the spell id that caused it
         * @param Damage how much was increased/decreased, negative values decrease, positive increase
         * @param powertype the power that was increased/decreased
         * \see Unit::ModifyPower
         */
        void EnergizeBySpell(Unit* pVictim, uint32 SpellID, uint32 Damage, Powers powertype);
        /**
         * Will do damage to the victim calculating how much should be done with the help of
         * \ref SpellNonMeleeDamage, \ref Unit::CalculateSpellDamage, \ref Unit::DealDamageMods and
         * \ref Unit::SendSpellNonMeleeDamageLog to update the combat log
         * @param pVictim the victim that should take damage
         * @param spellID id of the spell that will cause the damage
         * @param damage the initial damage to do
         * @return how much damage was actually done
         */
        uint32 SpellNonMeleeDamageLog(Unit* pVictim, uint32 spellID, uint32 damage);
        /**
         * This function only checks if the spell id is accurate, if it is then the other
         * \ref Unit::CastSpell is called which does the actual cast.
         * @param Victim victim that should be hit by the spell
         * @param spellId id of the spell to cast
         * @param triggered whether this was triggered by some outside circumstance or used as a button
         * press on you action bar, true means triggered by outside circumstance
         * @param castItem the item that cast the spell if any, usually NULL
         * @param triggeredByAura the \ref Aura that triggered the spell if any
         * @param originalCaster usually just \ref ObjectGuid constructor
         * @param triggeredBy the \ref SpellEntry that triggered this spell if any
         * \see Spell
         * \see SpellCastTargets
         * \todo What's the original caster?
         */
        void CastSpell(Unit* Victim, uint32 spellId, bool triggered, Item* castItem = NULL, Aura* triggeredByAura = NULL, ObjectGuid originalCaster = ObjectGuid(), SpellEntry const* triggeredBy = NULL);
        /**
         * Casts a spell simple and square, outputs some debugging info for some reasons, ie: if the
         * spellInfo is NULL it is logged and the function won't do anything. If the spell is triggered
         * by an \ref Aura and there's no originalCaster it is updated to be the cast of the \ref Aura
         * and the triggeredBy is set to be the \ref Aura s \ref SpellEntry. Some work is done to
         * work out if we should set a destination and/or source for the spell and it is then cast.
         *
         * Also, linked spells seem to be taken care of in here, but only the ones that should be
         * removed on cast, ie: \ref SpellLinkedType::SPELL_LINKED_TYPE_REMOVEONCAST. See
         * \ref SpellLinkedEntry for more info and \ref SpellLinkedType
         *
         * Finally calls \ref Spell::prepare on the \ref Spell and that's where it continues the
         * execution.
         *
         * @param Victim victim that should be hit by the spell
         * @param spellInfo info about the spell to cast
         * @param triggered whether this was triggered by some outside circumstance or used as a button
         * press on your action bar, true means triggered by outside circumstance
         * @param castItem the \ref Item that cast the spell if any, usually NULL
         * @param triggeredByAura the \ref Aura that triggered the spell if any
         * @param originalCaster usually just \ref ObjectGuid constructor
         * @param triggeredBy the \ref SpellEntry that triggered this spell if any
         * \see Spell
         * \see SpellCastTargets
         * \todo What's the original caster?
         * \todo Document the spell linked
         */
        void CastSpell(Unit* Victim, SpellEntry const* spellInfo, bool triggered, Item* castItem = NULL, Aura* triggeredByAura = NULL, ObjectGuid originalCaster = ObjectGuid(), SpellEntry const* triggeredBy = NULL);
        /**
         * Does pretty much the same thing as \ref Unit::CastSpell but uses the three bp0-bp2 variables
         * to change the \ref Spell s \ref Spell::m_currentBasePoints for the different
         * \ref SpellEffectIndexes. This also works as the first version of \ref Unit::CastSpell which
         * just does some checks and then calls the other one.
         *
         * @param Victim victim that should be hit by the spell
         * @param spellId id of the spell to be cast
         * @param bp0 this will change the \ref Spell s member \ref Spell::m_currentBasePoints for
         * \ref SpellEffectIndex::EFFECT_INDEX_0 to this value if it's not NULL.
         * @param bp1 this will change the \ref Spell s member \ref Spell::m_currentBasePoints for
         * \ref SpellEffectIndex::EFFECT_INDEX_1 to this value if it's not NULL.
         * @param bp2 this will change the \ref Spell s member \ref Spell::m_currentBasePoints for
         * \ref SpellEffectIndex::EFFECT_INDEX_2 to this value if it's not NULL.
         * @param triggered whether this was triggered by some outside circumstance or used as a button
         * press on your action bar, true means triggered by outside circumstance
         * @param castItem the \ref Item that cast this if any
         * @param triggeredByAura the \ref Aura that triggered this
         * @param originalCaster the original caster if any
         * @param triggeredBy the \ref SpellEntry that triggered this cast, if any
         * \todo What's the original caster?
         */
        void CastCustomSpell(Unit* Victim, uint32 spellId, int32 const* bp0, int32 const* bp1, int32 const* bp2, bool triggered, Item* castItem = NULL, Aura* triggeredByAura = NULL, ObjectGuid originalCaster = ObjectGuid(), SpellEntry const* triggeredBy = NULL);
        /**
         * Same idea for this one as for \ref Unit::CastCustomSpell with a change to the spellid being
         * exchanged for a \ref SpellEntry instead
         *
         * @param Victim victim that should be hit by the spell
         * @param spellInfo info about the spell to cast
         * @param bp0 this will change the \ref Spell s member \ref Spell::m_currentBasePoints for
         * \ref SpellEffectIndex::EFFECT_INDEX_0 to this value if it's not NULL.
         * @param bp1 this will change the \ref Spell s member \ref Spell::m_currentBasePoints for
         * \ref SpellEffectIndex::EFFECT_INDEX_1 to this value if it's not NULL.
         * @param bp2 this will change the \ref Spell s member \ref Spell::m_currentBasePoints for
         * \ref SpellEffectIndex::EFFECT_INDEX_2 to this value if it's not NULL.
         * @param triggered whether this was triggered by some outside circumstance or used as a button
         * press on your action bar, true means triggered by outside circumstance
         * @param castItem the \ref Item that cast this if any
         * @param triggeredByAura the \ref Aura that triggered this
         * @param originalCaster the original caster if any
         * @param triggeredBy the \ref SpellEntry that triggered this cast, if any
         * @param calculateDamage Indicates whether the damage calculation must be performed (in some cases, the calculation has already been executed).
         * \todo What's the original caster?
         */
        void CastCustomSpell(Unit* Victim, SpellEntry const* spellInfo, int32 const* bp0, int32 const* bp1, int32 const* bp2, bool triggered, Item* castItem = NULL, Aura* triggeredByAura = NULL, ObjectGuid originalCaster = ObjectGuid(), SpellEntry const* triggeredBy = NULL);
        /**
         * Same idea as for \ref Unit::CastSpell, but with the parameters x, y, z telling the
         * destination and source of the \ref SpellCastTargets depending on if the
         * \ref SpellEntry::Targets bitflags have the
         * \ref SpellCastTargetFlags::TARGET_FLAG_DEST_LOCATION  set for destination and
         * \ref SpellCastTargetFlags::TARGET_FLAG_SOURCE_LOCATION set for location
         *
         * @param x coord for source/dest
         * @param y coord for source/dest
         * @param z coord for source/dest
         * @param spellId id of the spell that was cast
         * @param triggered whether this was triggered by some outside circumstance or used as a button
         * press on your action bar, true means triggered by outside circumstance
         * @param castItem the \ref Item that cast this if any
         * @param triggeredByAura the \ref Aura that triggered this
         * @param originalCaster the original caster if any
         * @param triggeredBy the \ref SpellEntry that triggered this cast, if any
         */
        void CastSpell(float x, float y, float z, uint32 spellId, bool triggered, Item* castItem = NULL, Aura* triggeredByAura = NULL, ObjectGuid originalCaster = ObjectGuid(), SpellEntry const* triggeredBy = NULL);
        /**
         * Same idea as for \ref Unit::CastSpell, but with the parameters x, y, z telling the
         * destination and source of the \ref SpellCastTargets depending on if the
         * \ref SpellEntry::Targets bitflags have the
         * \ref SpellCastTargetFlags::TARGET_FLAG_DEST_LOCATION  set for destination and
         * \ref SpellCastTargetFlags::TARGET_FLAG_SOURCE_LOCATION set for location
         *
         * @param x coord for source/dest
         * @param y coord for source/dest
         * @param z coord for source/dest
         * @param spellInfo info about the spell to cast
         * @param triggered whether this was triggered by some outside circumstance or used as a button
         * press on your action bar, true means triggered by outside circumstance
         * @param castItem the \ref Item that cast this if any
         * @param triggeredByAura the \ref Aura that triggered this
         * @param originalCaster the original caster if any
         * @param triggeredBy the \ref SpellEntry that triggered this cast, if any
         */
        void CastSpell(float x, float y, float z, SpellEntry const* spellInfo, bool triggered, Item* castItem = NULL, Aura* triggeredByAura = NULL, ObjectGuid originalCaster = ObjectGuid(), SpellEntry const* triggeredBy = NULL);

        /**
         * Changes the display id for this \ref Unit to the native one that it usually has.
         * This is done by calling \ref Unit::SetDisplayId and \ref Unit::GetNativeDisplayId
         * like so:
         * \code{.cpp}
         * SetDisplayId(GetNativeDisplayId());
         * \endcode
         */
        void DeMorph();

        /**
         * This sends an AttackStateUpdate, some info about damage that you've done etc.
         * @param damageInfo the damage info used for knowing what to send
         * \see OpcodesList::SMSG_ATTACKERSTATEUPDATE
         * \todo Find out when and why this is sent
         */
        void SendAttackStateUpdate(CalcDamageInfo* damageInfo);
        /**
         * The same thing as \ref Unit::SendAttackStateUpdate but you send along all the parameters
         * that are needed instead of giving them through \ref CalcDamageInfo
         * @param HitInfo hit information as in the \ref CalcDamageInfo::HitInfo
         * @param target the target of the attack
         * @param damageSchoolMask the damageschoolmask as the one from:
         * \ref CalcDamageInfo::damageSchoolMask
         * @param Damage the damage that was done
         * @param AbsorbDamage how much of the damage that was absorbed
         * @param Resist how much of the damage that was resisted
         * @param TargetState the \ref VictimState of the target
         * @param BlockedAmount how much of the damage that was blocked
         * \todo What's the swingtype for?
         */
        void SendAttackStateUpdate(uint32 HitInfo, Unit* target, SpellSchoolMask damageSchoolMask, uint32 Damage, uint32 AbsorbDamage, uint32 Resist, VictimState TargetState, uint32 BlockedAmount);
        /**
         * Used to send a update to the combat log for all \ref Player/\ref Unit s in the vicinity.
         * @param log Info about who/what did damage to who and how etc, data needed for the packet
         * \see OpcodesList::SMSG_SPELLNONMELEEDAMAGELOG
         * \todo Is this actually for the combat log?
         */
        void SendSpellNonMeleeDamageLog(SpellNonMeleeDamage* log);
        /**
         * Same idea as for \ref Unit::SendSpellNonMeleeDamageLog but without the helping
         * \ref SpellNonMeleeDamage. This will set the \ref SpellNonMeleeDamage::HitInfo member to
         * the following before sending the packet:
         * \code {.cpp}
         * \ref HitInfo::SPELL_HIT_TYPE_UNK1 | \ref HitInfo::SPELL_HIT_TYPE_UNK3 | \ref HitInfo::SPELL_HIT_TYPE_UNK6
         * \endcode
         *
         * And if the \a CriticalHit parameter is true then it will add the flag
         * \ref HitInfo::SPELL_HIT_TYPE_CRIT
         *
         * @param target the target of the spell
         * @param SpellID id of the spell that was used
         * @param Damage the damage done including the damage that was resisted/absorbed/blocked etc.
         * Ie: damage + absorbed + resisted. This will be subtracted to the bare damage when inserted
         * into the \ref SpellNonMeleeDamage struct
         * @param damageSchoolMask mask for which kind of damage this is, see \ref SpellSchools for
         * possible values, the first set bit out of this mask will be used a the \ref SpellSchools
         * @param AbsorbedDamage how much of the damage that was absorbed
         * @param Resist how much of the damage that was resisted
         * @param PhysicalDamage whether or not this was physical damage
         * @param Blocked how much of the damage that was blocked
         * @param CriticalHit whether it was a critical hit or not
         * \see HitInfo
         * \see OpcodesList::SMSG_SPELLNONMELEEDAMAGELOG
         * \todo Is this actually for the combat log?
         */
        void SendSpellNonMeleeDamageLog(Unit* target, uint32 SpellID, uint32 Damage, SpellSchoolMask damageSchoolMask, uint32 AbsorbedDamage, uint32 Resist, bool PhysicalDamage, uint32 Blocked, bool CriticalHit = false);
        /**
         * Sends some data to the combat log about the periodic effects of an \ref Aura, it might be
         * periodic healing/damage etc. Perhaps it increases the amount of power you have as a rogue
         * and such. For more info on what exactly is sent etc see
         * \ref OpcodesList::SMSG_PERIODICAURALOG.
         * @param pInfo Info about the periodic effect of the \ref Aura
         * \see OpcodesList::SMSG_PERIODICAURALOG
         * \todo Is this actually for the combat log?
         */
        void SendPeriodicAuraLog(SpellPeriodicAuraLogInfo* pInfo);
        /**
         * Sends some data to the combat log about a spell that missed someone else. For more info
         * on what's sent see \ref OpcodesList::SMSG_SPELLLOGMISS
         * @param target the target of the \ref Spell that missed
         * @param spellID id of the spell that missed
         * @param missInfo info about how the spell actually missed ie: resisted/blocked/reflected etc.
         */
        void SendSpellMiss(Unit* target, uint32 spellID, SpellMissInfo missInfo);

        /**
         * Teleports a \ref Creature or \ref Player to some coordinates within the same \ref Map,
         * hence the name. If it's a \ref Creature that's being teleported it needs to have it's
         * \ref MovementGenerator interrupted before the teleport and then reset afterwards. See
         * \ref MovementGenerator::Reset and \ref MovementGenerator::Interrupt. Also, after moving
         * a \ref Creature a hearbeat needs to be sent to inform the clients about the new location,
         * this is done using \ref Unit::SendHeartBeat and the actual move of the \ref Creature is
         * done with \ref Map::CreatureRelocation
         * @param x the new x coord
         * @param y the new y coord
         * @param z the new z coord
         * @param orientation the orientation after teleport, 0 is north and it's measured in radians
         * @param casting used to decide whether a spell cast should be interrupted if a \ref Player
         * is going to be teleported, see \ref TeleportToOptions::TELE_TO_SPELL, the idea is that
         * you don't interrupt spellcasting at teleport if the spell is meant to teleport you as
         * that would defeat the purpose of trying to teleport one self :)
         */
        void NearTeleportTo(float x, float y, float z, float orientation, bool casting = false);
        /**
         * Moves this \ref Unit to the given position in x,y,z coordinates. we can choose whether or
         * not we want to generate a path to the target or just move straight there and if we would
         * like to force the destination when creating the \ref PathFinder, only interesting
         * if we have set generatePath to true.
         *
         * Taken from comments: recommend use \ref Unit::MonsterMove / \ref Unit::MonsterMoveWithSpeed
         * for most case that correctly work with movegens, mmaps
         * @param x the x coord to move to
         * @param y the y coord to move to
         * @param z the z coord to move to
         * @param speed at which speed the \ref Unit should move
         * @param generatePath whether a real path should be generated using a \ref PathFinder which
         * will try to create a smooth path. if false we just go from current pos to given pos
         * @param forceDestination if this is true it seems that we will try to get to our target
         * even if there's something in the way. Otherwise we stop before we get there if there
         * are obstacles
         * \todo In what is the speed expressed? What is normal walking/running speed?
         * \todo Is the dox about forceDestination correct?
         */
        void MonsterMoveWithSpeed(float x, float y, float z, float speed, bool generatePath = false, bool forceDestination = false);

        // if used additional args in ... part then floats must explicitly casted to double
        /**
         * Tells nearby \ref Unit s and such that this \ref Unit has moved to a new position using
         * \ref OpcodesList::MSG_MOVE_HEARTBEAT which will send the new position to all clients etc
         * in the same \ref Cell
         */
        void SendHeartBeat();

        /**
         * Checks if this \ref Unit has the movement flag \ref MovementFlags::MOVEFLAG_LEVITATING
         * @return true if the \ref Unit is levitating, ie: it has the flag MOVEFLAG_LEVITATING, false
         * otherwise
         * \see MovementInfo::HasMovementFlag
         */
        bool IsLevitating() const { return m_movementInfo.HasMovementFlag(MOVEFLAG_LEVITATING); }
        /**
         * Checks if this \ref Unit has the movement flag \ref MovementFlags::MOVEFLAG_WALK_MODE
         * @return true if the \ref Unit is walking, ie: it has the flag MOVEFLAG_WALK_MODE, false
         * otherwise
         * \see MovementInfo::HasMovementFlag
         */
        bool IsWalking() const { return m_movementInfo.HasMovementFlag(MOVEFLAG_WALK_MODE); }
        /**
         * Check if this \ref Unit has the movement flag \ref MovementFlags::MOVEFLAG_ROOT
         * @return true if the \ref Unit is rooted to the ground (can't move), ie: has the flag
         * MOVEFLAG_ROOT, false otherwise
         * \see MovementInfo::HasMovementFlag
         */
        bool IsRooted() const { return m_movementInfo.HasMovementFlag(MOVEFLAG_ROOT); }
        virtual void SetLevitate(bool /*enabled*/) {}
        virtual void SetSwim(bool /*enabled*/) {}
        virtual void SetCanFly(bool /*enabled*/) {}
        virtual void SetFeatherFall(bool /*enabled*/) {}
        virtual void SetHover(bool /*enabled*/) {}
        /**
         * Roots or unroots this \ref Unit depending on the enabled parameter.
         * @param enabled whether we should root (true) or unroot (false) this \ref Unit
         * \see Player::SetRoot
         */
        virtual void SetRoot(bool /*enabled*/) {}
        /**
         * Changes this \ref Unit s ability to walk on water.
         * @param enabled whether this \ref Unit should be able to walk on water (true) or not
         * be able to (false)
         * \see Player::SetWaterWalk
         */
        virtual void SetWaterWalk(bool /*enabled*/) {}

        /**
         * Turns this \ref Unit towards the given one.
         * @param target the \ref Unit we want to be turned towards
         * \see WorldObject::SetOrientation
         * \see WorldObejct::GetAngle
         */
        void SetInFront(Unit const* target);
        /**
         * Sets this \ref Unit to face a certain angle.
         * @param ori where we should start facing, measured in radians, 0 = north pi/2 = east etc.
         * \todo is pi/2 = east or west? Logic says east?
         */
        void SetFacingTo(float ori);
        /**
         * Does pretty much the same thing as \ref Unit::SetInFront but calls \ref Unit::SetFacingTo
         * instead, which uses a \ref MoveSplineInit instead of just changing the angle.
         * @param pObject the \ref WorldObject we should be facing
         * \todo What difference does it make to use \ref MoveSplineInit instead of just directly
         * changing the angle? Is it smoother?
         */
        void SetFacingToObject(WorldObject* pObject);

        /**
         * Checks whether or not this \ref Unit is alive by checking the \ref Unit::m_deathState member
         * for the value \ref DeathState::ALIVE
         * @return true if this \ref Unit is alive, false otherwise
         */
        bool IsAlive() const { return (m_deathState == ALIVE); };
        bool IsDying() const { return (m_deathState == JUST_DIED); }
        /**
         * Checks whether or not this \ref Unit is dead by checking the \ref Unit::m_deathState member
         * for the value \ref DeathState::DEAD or \ref DeathState::CORPSE
         * @return true if this \ref Unit is dead or a corpse (also dead), false otherwise
         */
        bool IsDead() const { return (m_deathState == DEAD || m_deathState == CORPSE); };
        /**
         * Returns the current \ref DeathState for this \ref Unit.
         * @return the value of the member \ref Unit::m_deathState
         */
        DeathState GetDeathState() const { return m_deathState; };
        /**
         * Changes the \ref DeathState for this \ref Unit and making sure that some things that should
         * happen when that changes happen, ie: you just died, then you're auras should be removed,
         * any combopoints that you had should be removed etc.
         *
         * This is overwritten to do different things in at least \ref Player, \ref Creature, \ref Pet
         * @param s the new \ref DeathState this \ref Unit should get
         */
        virtual void SetDeathState(DeathState s);           // overwritten in Creature/Player/Pet

        ObjectGuid const& GetOwnerGuid() const { return  GetGuidValue(UNIT_FIELD_SUMMONEDBY); }
        void SetOwnerGuid(ObjectGuid owner) { SetGuidValue(UNIT_FIELD_SUMMONEDBY, owner); }
        ObjectGuid const& GetCreatorGuid() const { return GetGuidValue(UNIT_FIELD_CREATEDBY); }
        void SetCreatorGuid(ObjectGuid creator) { SetGuidValue(UNIT_FIELD_CREATEDBY, creator); }
        ObjectGuid const& GetPetGuid() const { return GetGuidValue(UNIT_FIELD_SUMMON); }
        void SetPetGuid(ObjectGuid pet) { SetGuidValue(UNIT_FIELD_SUMMON, pet); }
        ObjectGuid const& GetCharmerGuid() const { return GetGuidValue(UNIT_FIELD_CHARMEDBY); }
        void SetCharmerGuid(ObjectGuid owner) { SetGuidValue(UNIT_FIELD_CHARMEDBY, owner); }
        ObjectGuid const& GetCharmGuid() const { return GetGuidValue(UNIT_FIELD_CHARM); }
        void SetCharmGuid(ObjectGuid charm) { SetGuidValue(UNIT_FIELD_CHARM, charm); }
        ObjectGuid const& GetTargetGuid() const { return GetGuidValue(UNIT_FIELD_TARGET); }
        void SetTargetGuid(ObjectGuid targetGuid) { SetGuidValue(UNIT_FIELD_TARGET, targetGuid); }
        ObjectGuid const& GetChannelObjectGuid() const { return GetGuidValue(UNIT_FIELD_CHANNEL_OBJECT); }
        void SetChannelObjectGuid(ObjectGuid targetGuid) { SetGuidValue(UNIT_FIELD_CHANNEL_OBJECT, targetGuid); }

        /**
         * Returns the currently spawned minipet, this has an implementation in \ref Player
         * @return the current \ref Pet for this \ref Player
         */
        virtual Pet* GetMiniPet() const { return NULL; }    // overwrited in Player

        /**
         * Gets either the current charmer (ie mind control) or the owner of this \ref Unit
         * @return the \ref ObjectGuid of either the charmer of this \ref Unit or the owner of it
         */
        ObjectGuid const& GetCharmerOrOwnerGuid() const { return GetCharmerGuid() ? GetCharmerGuid() : GetOwnerGuid(); }
        /**
         * Same thing as \ref Unit::GetCharmerOrOwnerGuid but with the exception that it returns
         * it's own \ref ObjectGuid if it has no owner or charmer.
         * @return either the charmers, owners or it's own \ref ObjectGuid
         */
        ObjectGuid const& GetCharmerOrOwnerOrOwnGuid() const
        {
            if (ObjectGuid const& guid = GetCharmerOrOwnerGuid())
            {
                return guid;
            }
            return GetObjectGuid();
        }
        /**
         * Checks if the charmer or owner is a \ref Player
         * @return true if the charmer or owner is a \ref Player, false otherwise
         * \see ObjectGuid::IsPlayer
         */
        bool IsCharmedOwnedByPlayerOrPlayer() const { return GetCharmerOrOwnerOrOwnGuid().IsPlayer(); }

        /**
         * Get's the \ref Player that owns the \ref SpellModifier for this \ref Unit, if this
         * \ref Unit is a \ref Player it's the owner, but if it's a \ref Pet och \ref Totem then
         * then owner of the totem is returned if it's a \ref Player
         * @return The \ref SpellModifier owner for this \ref Unit
         */
        Player* GetSpellModOwner() const;

        /**
         * Returns the \ref Unit that owns this \ref Unit if any
         * @return the \ref Unit that owns this one, NULL if there is no owner
         * \see Unit::GetOwnerGuid
         */
        Unit* GetOwner() const;
        /**
         * Returns the \ref Pet for this \ref Unit if any
         * @return the \ref Pet that is associated with this \ref Unit if any, NULL if there is none
         * \see Unit::GetPetGuid
         */
        Pet* GetPet() const;
        /**
         * Returns the \ref Unit that's currently charming this one if any.
         * @return the \ref Unit that's charming this one, NULL if there is none
         */
        Unit* GetCharmer() const;
        /**
         * Returns the \ref Unit that this one is currently charming
         * @return the \ref Unit that this one is charming, NULL if there is none
         */
        Unit* GetCharm() const;
        /**
         * Removes all \ref Aura s causing this \ref Unit to be charmed/possessed, the \ref Aura s
         * that cause this are:
         * - \ref AuraType::SPELL_AURA_MOD_CHARM
         * - \ref AuraType::SPELL_AURA_MOD_POSSESS
         * - \ref AuraType::SPELL_AURA_MOD_POSSESS_PET
         */
        void Uncharm();
        /**
         * Does the same as \ref Unit::GetCharmerOrOwnerGuid but returns the \ref Unit for that instead
         * @return the \ref Unit that's charming this one or owning it, NULL if there is none
         */
        Unit* GetCharmerOrOwner() const { return GetCharmerGuid() ? GetCharmer() : GetOwner(); }
        /**
         * Does the same a \ref Unit::GetCharmerOrOwner but if there is none of those it returns itself
         * @return a \ref Unit that's either owning or charming this one or just itself.
         */
        Unit* GetCharmerOrOwnerOrSelf()
        {
            if (Unit* u = GetCharmerOrOwner())
            {
                return u;
            }

            return this;
        }
        bool IsCharmerOrOwnerPlayerOrPlayerItself() const;
        Player* GetCharmerOrOwnerPlayerOrPlayerItself();
        Player const* GetCharmerOrOwnerPlayerOrPlayerItself() const;

        /**
         * Set's the current \ref Pet for this \ref Unit
         * @param pet The \ref Pet to add to this \ref Unit
         */
        void SetPet(Pet* pet);
        /**
         * Set's who we're currently charming
         * @param pet The \ref Unit to set as charmed by us
         */
        void SetCharm(Unit* pet);

        /**
         * Adds a guardian to this \ref Unit which will generally defend this \ref Unit when on a
         * threat list.
         * @param pet the guardian to add
         * \see Unit::m_guardianPets
         */
        void AddGuardian(Pet* pet);
        /**
         * Removes a guardian from this \ref Unit
         * @param pet the guardian to remove
         * \see Unit::m_guardianPets
         */
        void RemoveGuardian(Pet* pet);
        /**
         * Removes all current guardians from this \ref Unit
         */
        void RemoveGuardians();
        /**
         * Finds a guardian by it's entry, this is the entry in character.character_pet
         * @param entry the entry to find
         * @return the guardian/\ref Pet found or NULL if there's no such entry in the db
         * \todo Is it the correct entry
         */
        Pet* FindGuardianWithEntry(uint32 entry);

        /**
         * Is this \ref Unit charmed?
         * @return true if the \ref Unit has a charmer, false otherwise
         * \see Unit::GetCharmerGuid
         */
        bool IsCharmed() const { return !GetCharmerGuid().IsEmpty(); }

        /**
         * There's only \ref CharmInfo available if this \ref Unit is in fact charmed by someone
         * @return The \ref CharmInfo for this \ref Unit if any, NULL otherwise
         */
        CharmInfo* GetCharmInfo() { return m_charmInfo; }
        /**
         * Init the \ref CharmInfo struct with data about the \ref Unit that will be charmed
         * @param charm the \ref Unit that is to be charmed
         * @return the created \ref CharmInfo
         * \todo Is the charm param really the unit to be charmed?
         */
        CharmInfo* InitCharmInfo(Unit* charm);

        /**
         * Get's the \ref ObjectGuid for a certain totem type that this \ref Unit has spawned
         * @param slot the slot to get the \ref ObjectGuid for
         * @return the \ref ObjectGuid for the given totem slot
         */
        ObjectGuid const& GetTotemGuid(TotemSlot slot) const { return m_TotemSlot[slot]; }
        /**
         * Gets a certain \ref Totem that this \ref Unit has spawned
         * @param slot the slot to get the \ref Totem for
         * @return The requested totem if there is any spawned, NULL otherwise
         */
        Totem* GetTotem(TotemSlot slot) const;
        /**
         * @return True if all totems slots are used (spawned), false otherwise
         */
        bool IsAllTotemSlotsUsed() const;

        /**
         * This is internal code that should only be called from the \ref Totem summon code
         * @param slot
         * @param totem
         * \internal
         */
        void _AddTotem(TotemSlot slot, Totem* totem);       // only for call from Totem summon code
        /**
         * This is internal code that should only be called from the \ref Totem class.
         * @param totem
         * \internal
         */
        void _RemoveTotem(Totem* totem);                    // only for call from Totem class

        /**
         * This will call the given function for all controlled \ref Unit s, for an example of
         * how one such function could look please have a look at \ref CallForAllControlledUnitsExample
         *
         * The functors operator() should have the following signature:
         * \code{.cpp}
         * void operator()(Unit* unit) { ... };
         * \endcode
         * @param func the functor object used to call for each \ref Unit that we will find matching
         * the mask
         * @param controlledMask a mask telling which of the controlled \ref Unit s we want to call
         * the functor for
         */
        template<typename Func>
        void CallForAllControlledUnits(Func const& func, uint32 controlledMask);
        /**
         * Works pretty much the same way as \ref Unit::CallForAllControlledUnits but instead
         * the functors operator() should have the following signature:
         * \code{.cpp}
         * bool operator()(Unit* unit) { ... };
         * \endcode
         * @param func a functor object used to call for each \ref Unit that we will find matching
         * the mask
         * @param controlledMask a mask telling which of the controlled \ref Unit s we want to call
         * the functor for
         * @return true if the functor returned true for one of the \ref Unit s included by the
         * controlledMask, false if none of them returned true
         * \see Unit::isAttackingPlayer
         */
        template<typename Func>
        bool CheckAllControlledUnits(Func const& func, uint32 controlledMask) const;

        /**
         * Adds a \ref SpellAuraHolder
         * @param holder the holder to add
         * @return true if the holder was added, false otherwise
         */
        bool AddSpellAuraHolder(SpellAuraHolder* holder);
        /**
         * Adds a \ref Aura to \ref Unit::m_modAuras
         * @param aura the \ref Aura to add
         */
        void AddAuraToModList(Aura* aura);


        /**
         * Removes an \ref Aura and sets the reason for removal inside the \ref Aura.
         *
         * removing specific aura stack (From old comment)
         * @param aura the \ref Aura to remove
         * @param mode the reason why it is being removed
         * \see Aura::SetRemoveMode
         */
        void RemoveAura(Aura* aura, AuraRemoveMode mode = AURA_REMOVE_BY_DEFAULT);
        /**
         * Removes an \ref Aura by spell id and the effect index for that spell to find out
         * which \ref Aura to remove.
         * @param spellId id of the spell which has the sought \ref Aura somewhere
         * @param effindex the effect index for the spell to find the right \ref Aura
         * @param except if != NULL we will not remove this \ref Aura if found
         */
        void RemoveAura(uint32 spellId, SpellEffectIndex effindex, Aura* except = NULL);
        /**
         * Removes a \ref SpellAuraHolder from this \ref Unit. This will remove all the effects that
         * are currently stored in the \ref SpellAuraHolder.
         * @param holder holder to be removed
         * @param mode reason for removal
         */
        void RemoveSpellAuraHolder(SpellAuraHolder* holder, AuraRemoveMode mode = AURA_REMOVE_BY_DEFAULT);
        /**
         * Removes a single \ref Aura from a \ref SpellAuraHolder to cancel out just one effect of a
         * \ref Spell.
         * @param holder the holder to remove the \ref Aura from
         * @param index the effect index to tell which \ref Aura we want to remove
         * @param mode the reason for removing it
         */
        void RemoveSingleAuraFromSpellAuraHolder(SpellAuraHolder* holder, SpellEffectIndex index, AuraRemoveMode mode = AURA_REMOVE_BY_DEFAULT);
        /**
         * Does the same thing as \ref Unit::RemoveSingleAuraFromSpellAuraHolder but with spell id
         * instead of a \ref SpellAuraHolder
         * @param id id of the spell to find the \ref Aura in
         * @param index the effect index to tell which \ref Aura we want to remove
         * @param casterGuid guid of the caster to filter it out to just one \ref Aura to remove
         * @param mode reason for removal
         */
        void RemoveSingleAuraFromSpellAuraHolder(uint32 id, SpellEffectIndex index, ObjectGuid casterGuid, AuraRemoveMode mode = AURA_REMOVE_BY_DEFAULT);

        /**
         * Removes all \ref Aura s that a certain spell would cause via it's effects (up to 3 of them
         * per \ref Aura).
         *
         * From old doc: removing specific aura stacka by diff reasons and selections
         * @param spellId id of the spell causing the \ref Aura s you would like to remove
         * @param except a spell that shouldn't be included in the removal
         * @param mode reason for removal
         * \see SpellEntry::Effect
         */
        void RemoveAurasDueToSpell(uint32 spellId, SpellAuraHolder* except = NULL, AuraRemoveMode mode = AURA_REMOVE_BY_DEFAULT);
        /**
         * Removes all \ref Aura s that a certain spell cast by a certain \ref Item would cause via
         * it's effects (up to 3 of them per \ref Aura).
         * @param castItem the \ref Item that cast the spell
         * @param spellId id of the spell causing the \ref Aura s you would like to remove
         */
        void RemoveAurasDueToItemSpell(Item* castItem, uint32 spellId);
        /**
         * Removes all \ref Aura s applied by spells casted by a certain \ref Player / \ref Unit
         * @param casterGuid \ref ObjectGuid of the caster
         */
        void RemoveAurasByCaster(ObjectGuid casterGuid);
        /**
         * Removes all \ref Aura s that a certain spell cast by a certain \ref Player / \ref Unit
         * would cause via it's effects (up to 3 of them per \ref Aura)
         * @param spellId id of the \ref Spell causing the \ref Aura s you would like to remove
         * @param casterGuid \ref ObjectGuid of the caster
         */
        void RemoveAurasByCasterSpell(uint32 spellId, ObjectGuid casterGuid);
        /**
         * Removes all \ref Aura s caused by a certain spell because it was canceled.
         * @param spellId id of the \ref Spell causing the \ref Aura s you would like to remove
         */
        void RemoveAurasDueToSpellByCancel(uint32 spellId);

        // removing unknown aura stacks by diff reasons and selections
        /**
         * From old doc: removing unknown aura stacks by diff reasons and selections
         * \todo Document and find out what it does
         */
        void RemoveNotOwnTrackedTargetAuras();
        /**
         * Removes all \ref SpellAuraHolder s that have the given \ref Mechanics mask which is created
         * by doing something like the following if we want a mask for \ref Mechanics::MECHANIC_SAPPED:
         * \code{.cpp}
         * uint32 mask = 1 << (MECHANIC_SAPPED - 1);
         * \endcode
         * @param mechMask a mask of \ref Mechanics, see \ref MECHANIC_NOT_REMOVED_BY_SHAPESHIFT,
         * \ref IMMUNE_TO_ROOT_AND_SNARE_MASK for examples
         * @param exceptSpellId id of a \ref Spell that shouldn't be removed
         * @param non_positive if we should remove non positive \ref Aura s or not, defaults to false
         */
        void RemoveAurasAtMechanicImmunity(uint32 mechMask, uint32 exceptSpellId, bool non_positive = false);
        /**
         * Removes all \ref Spell s that cause the given \ref AuraType
         * @param auraType the type of auras we would like to remove spells for
         */
        void RemoveSpellsCausingAura(AuraType auraType);
        /**
         * Same as \ref Unit::RemoveSpellsCausingAura but with an exception
         * for a \ref SpellAuraHolder that shouldn't be removed
         * @param auraType the type of auras we would like to remove spells for
         * @param except this will be excepted from removal
         */
        void RemoveSpellsCausingAura(AuraType auraType, SpellAuraHolder* except);
        /**
         * Same as \ref Unit::RemoveSpellsCausingAura but for a matching caster aswell.
         * @param auraType the type of auras we would like to remove spells for
         * @param casterGuid remove the aura only if the caster is equal to this guid
         */
        void RemoveSpellsCausingAura(AuraType auraType, ObjectGuid casterGuid);
        /**
         * Removes all ranks of the given \ref Spell, ie: if the spellid of rank 1 inner fire is
         * given all the ranks of it will be removed.
         * @param spellId id of the spell we want to remove all ranks for
         */
        void RemoveRankAurasDueToSpell(uint32 spellId);
        /**
         *
         * @param holder
         * @return true if we could remove something (and did), false otherwise
         * \todo Document what this does and break into smaller functions!
         */
        bool RemoveNoStackAurasDueToAuraHolder(SpellAuraHolder* holder);
        /**
         * Removes all \ref Aura s that have the given interrupt flags
         * @param flags see \ref AuraInterruptFlags for possible flags
         */
        void RemoveAurasWithInterruptFlags(uint32 flags);
        /**
         * Removes all \ref Aura s that have the given attributes
         * @param flags see \ref SpellAttributes for possible values
         */
        void RemoveAurasWithAttribute(uint32 flags);
        /**
         * Removes all \ref Aura s which can be dispelled by the given \ref DispelType
         * @param type the given type that you want to remove all \ref Aura s for
         * @param casterGuid if this isn't 0 it will be checked that the caster of the \ref Spell is
         * the same as the given guid before removal.
         */
        void RemoveAurasWithDispelType(DispelType type, ObjectGuid casterGuid = ObjectGuid());
        /**
         * Removes all \ref Aura s.
         * @param mode the reason for removal
         */
        void RemoveAllAuras(AuraRemoveMode mode = AURA_REMOVE_BY_DEFAULT);
        /**
         * Removes all \ref Aura s on this \ref Unit s death. Removes all visible \ref Aura s and
         * disabled the mods for the passive ones (taken from old docs). The reason used is
         * \ref AuraRemoveMode::AURA_REMOVE_BY_DEATH
         * \todo Where does it remove the passive ones?
         */
        void RemoveAllAurasOnDeath();
        /**
         * used when evading to remove all auras except some special auras. Linked and flying
         * \ref Aura s shouldn't be removed on evade.
         * \todo Are linked and flying auras really not removed on evade?
         */
        void RemoveAllAurasOnEvade();

        // removing specific aura FROM stack by diff reasons and selections
        void RemoveAuraHolderFromStack(uint32 spellId, uint32 stackAmount = 1, ObjectGuid casterGuid = ObjectGuid(), AuraRemoveMode mode = AURA_REMOVE_BY_DEFAULT);
        void RemoveAuraHolderDueToSpellByDispel(uint32 spellId, uint32 stackAmount, ObjectGuid casterGuid, Unit* dispeller);

        void DelaySpellAuraHolder(uint32 spellId, int32 delaytime, ObjectGuid casterGuid);

        void SetCreateStat(Stats stat, float val) { m_createStats[stat] = val; }
        void SetCreateHealth(uint32 val) { SetUInt32Value(UNIT_FIELD_BASE_HEALTH, val); }
        uint32 GetCreateHealth() const { return GetUInt32Value(UNIT_FIELD_BASE_HEALTH); }
        void SetCreateMana(uint32 val) { SetUInt32Value(UNIT_FIELD_BASE_MANA, val); }
        uint32 GetCreateMana() const { return GetUInt32Value(UNIT_FIELD_BASE_MANA); }
        uint32 GetCreatePowers(Powers power) const;
        float GetCreateStat(Stats stat) const { return m_createStats[stat]; }

        void SetCurrentCastedSpell(Spell* pSpell);
        virtual void ProhibitSpellSchool(SpellSchoolMask /*idSchoolMask*/, uint32 /*unTimeMs*/) { }
        void InterruptSpell(CurrentSpellTypes spellType, bool withDelayed = true);
        void FinishSpell(CurrentSpellTypes spellType, bool ok = true);

        bool IsClientControlled(Player const* exactClient = nullptr) const;

        // set withDelayed to true to account delayed spells as casted
        // delayed+channeled spells are always accounted as casted
        // we can skip channeled or delayed checks using flags
        bool IsNonMeleeSpellCasted(bool withDelayed, bool skipChanneled = false, bool skipAutorepeat = false, bool forMovement = false, bool forAutoIgnore = false) const;

        // set withDelayed to true to interrupt delayed spells too
        // delayed+channeled spells are always interrupted
        void InterruptNonMeleeSpells(bool withDelayed, uint32 spellid = 0);

        Spell* GetCurrentSpell(CurrentSpellTypes spellType) const { return m_currentSpells[spellType]; }
        Spell* GetCurrentSpell(uint32 spellType) const { return m_currentSpells[spellType]; }
        Spell* FindCurrentSpellBySpellId(uint32 spell_id) const;

        bool CheckAndIncreaseCastCounter();
        void DecreaseCastCounter() { if (m_castCounter) { --m_castCounter; } }

        ObjectGuid m_ObjectSlotGuid[4];
        uint32 m_detectInvisibilityMask;
        uint32 m_invisibilityMask;

        ShapeshiftForm GetShapeshiftForm() const { return ShapeshiftForm(GetByteValue(UNIT_FIELD_BYTES_1, 2)); }
        void  SetShapeshiftForm(ShapeshiftForm form) { SetByteValue(UNIT_FIELD_BYTES_1, 2, form); }

        bool IsInFeralForm() const
        {
            ShapeshiftForm form = GetShapeshiftForm();
            return form == FORM_CAT || form == FORM_BEAR || form == FORM_DIREBEAR;
        }

        bool IsInDisallowedMountForm() const
        {
            ShapeshiftForm form = GetShapeshiftForm();
            return form != FORM_NONE && form != FORM_BATTLESTANCE && form != FORM_BERSERKERSTANCE && form != FORM_DEFENSIVESTANCE &&
                   form != FORM_SHADOW && form != FORM_STEALTH;
        }

        float m_modMeleeHitChance;
        float m_modRangedHitChance;
        float m_modSpellHitChance;
        int32 m_baseSpellCritChance;

        float m_threatModifier[MAX_SPELL_SCHOOL];
        float m_modAttackSpeedPct[3];

        // Event handler
        EventProcessor m_Events;

        // stat system
        bool HandleStatModifier(UnitMods unitMod, UnitModifierType modifierType, float amount, bool apply);
        void SetModifierValue(UnitMods unitMod, UnitModifierType modifierType, float value) { m_auraModifiersGroup[unitMod][modifierType] = value; }
        float GetModifierValue(UnitMods unitMod, UnitModifierType modifierType) const;
        float GetTotalStatValue(Stats stat) const;
        float GetTotalAuraModValue(UnitMods unitMod) const;
        SpellSchools GetSpellSchoolByAuraGroup(UnitMods unitMod) const;
        Stats GetStatByAuraGroup(UnitMods unitMod) const;
        Powers GetPowerTypeByAuraGroup(UnitMods unitMod) const;
        bool CanModifyStats() const { return m_canModifyStats; }
        void SetCanModifyStats(bool modifyStats) { m_canModifyStats = modifyStats; }
        virtual bool UpdateStats(Stats stat) = 0;
        virtual bool UpdateAllStats() = 0;
        virtual void UpdateResistances(uint32 school) = 0;
        virtual void UpdateArmor() = 0;
        virtual void UpdateMaxHealth() = 0;
        virtual void UpdateMaxPower(Powers power) = 0;
        virtual void UpdateAttackPowerAndDamage(bool ranged = false) = 0;
        virtual void UpdateDamagePhysical(WeaponAttackType attType) = 0;
        float GetTotalAttackPowerValue(WeaponAttackType attType) const;
        float GetWeaponDamageRange(WeaponAttackType attType , WeaponDamageRange type) const;
        void SetBaseWeaponDamage(WeaponAttackType attType , WeaponDamageRange damageRange, float value) { m_weaponDamage[attType][damageRange] = value; }

        SpellSchools GetWeaponDamageSchool(WeaponAttackType attType, uint8 index = 0) const { return m_weaponDamageInfo.weapon[attType].damage[index].school; }
        void SetWeaponDamageSchool(WeaponAttackType attType, SpellSchools school, uint8 index = 0) { m_weaponDamageInfo.weapon[attType].damage[index].school = school; }


        // Visibility system
        UnitVisibility GetVisibility() const { return m_Visibility; }
        void SetVisibility(UnitVisibility x);
        void UpdateVisibilityAndView() override;            // overwrite WorldObject::UpdateVisibilityAndView()

        // common function for visibility checks for player/creatures with detection code
        bool IsVisibleForOrDetect(Unit const* u, WorldObject const* viewPoint, bool detect, bool inVisibleList = false, bool is3dDistance = true) const;
        bool CanDetectInvisibilityOf(Unit const* u) const;

        // virtual functions for all world objects types
        bool IsVisibleForInState(Player const* u, WorldObject const* viewPoint, bool inVisibleList) const override;
        // function for low level grid visibility checks in player/creature cases
        virtual bool IsVisibleInGridForPlayer(Player* pl) const = 0;
        bool IsInvisibleForAlive() const;

        TrackedAuraTargetMap&       GetTrackedAuraTargets(TrackedAuraType type)       { return m_trackedAuraTargets[type]; }
        TrackedAuraTargetMap const& GetTrackedAuraTargets(TrackedAuraType type) const { return m_trackedAuraTargets[type]; }
        SpellImmuneList m_spellImmune[MAX_SPELL_IMMUNITY];

        // Threat related methods
        bool CanHaveThreatList(bool ignoreAliveState = false) const;
        void AddThreat(Unit* pVictim, float threat = 0.0f, bool crit = false, SpellSchoolMask schoolMask = SPELL_SCHOOL_MASK_NONE, SpellEntry const* threatSpell = NULL);
        float ApplyTotalThreatModifier(float threat, SpellSchoolMask schoolMask = SPELL_SCHOOL_MASK_NORMAL);
        void DeleteThreatList();
        bool IsSecondChoiceTarget(Unit* pTarget, bool checkThreatArea);
        bool SelectHostileTarget();
        void TauntApply(Unit* pVictim);
        void TauntFadeOut(Unit* taunter);
        void FixateTarget(Unit* pVictim);
        ObjectGuid GetFixateTargetGuid() const { return m_fixateTargetGuid; }
        ThreatManager& GetThreatManager() { return m_ThreatManager; }
        ThreatManager const& GetThreatManager() const { return m_ThreatManager; }
        void AddHatedBy(HostileReference* pHostileReference) { m_HostileRefManager.insertFirst(pHostileReference); };
        void RemoveHatedBy(HostileReference* /*pHostileReference*/) { /* nothing to do yet */ }
        HostileRefManager& GetHostileRefManager() { return m_HostileRefManager; }

        Aura* GetAura(uint32 spellId, SpellEffectIndex effindex);
        Aura* GetAura(AuraType type, SpellFamily family, uint64 familyFlag, ObjectGuid casterGuid = ObjectGuid());
        SpellAuraHolder* GetSpellAuraHolder(uint32 spellid) const;
        SpellAuraHolder* GetSpellAuraHolder(uint32 spellid, ObjectGuid casterGUID) const;

        SpellAuraHolderMap&       GetSpellAuraHolderMap()       { return m_spellAuraHolders; }
        SpellAuraHolderMap const& GetSpellAuraHolderMap() const { return m_spellAuraHolders; }
        /**
         * Get's a list of all the \ref Aura s of the given \ref AuraType that are currently
         * affecting this \ref Unit.
         * @param type the aura type we want to find
         * @return A list of the auras currently applied to the \ref Unit with the given \ref AuraType
         * \see Unit::m_modAuras
         */
        AuraList const& GetAurasByType(AuraType type) const { return m_modAuras[type]; }
        void ApplyAuraProcTriggerDamage(Aura* aura, bool apply);

        int32 GetTotalAuraModifier(AuraType auratype) const;
        float GetTotalAuraMultiplier(AuraType auratype) const;
        int32 GetMaxPositiveAuraModifier(AuraType auratype) const;
        int32 GetMaxNegativeAuraModifier(AuraType auratype) const;

        int32 GetTotalAuraModifierByMiscMask(AuraType auratype, uint32 misc_mask) const;
        float GetTotalAuraMultiplierByMiscMask(AuraType auratype, uint32 misc_mask) const;
        int32 GetMaxPositiveAuraModifierByMiscMask(AuraType auratype, uint32 misc_mask) const;
        int32 GetMaxNegativeAuraModifierByMiscMask(AuraType auratype, uint32 misc_mask) const;

        int32 GetTotalAuraModifierByMiscValue(AuraType auratype, int32 misc_value) const;
        float GetTotalAuraMultiplierByMiscValue(AuraType auratype, int32 misc_value) const;
        int32 GetMaxPositiveAuraModifierByMiscValue(AuraType auratype, int32 misc_value) const;
        int32 GetMaxNegativeAuraModifierByMiscValue(AuraType auratype, int32 misc_value) const;

        Aura* GetDummyAura(uint32 spell_id) const;

        uint32 m_AuraFlags;

        uint32 GetDisplayId() const { return GetUInt32Value(UNIT_FIELD_DISPLAYID); }
        void SetDisplayId(uint32 modelId);
        uint32 GetNativeDisplayId() const { return GetUInt32Value(UNIT_FIELD_NATIVEDISPLAYID); }
        void SetNativeDisplayId(uint32 modelId) { SetUInt32Value(UNIT_FIELD_NATIVEDISPLAYID, modelId); }
        void SetTransform(uint32 spellid) { m_transform = spellid;}
        uint32 GetTransform() const { return m_transform;}

        // at any changes to scale and/or displayId
        void UpdateModelData();
        float GetObjectScaleMod() const;

        DynamicObject* GetDynObject(uint32 spellId, SpellEffectIndex effIndex);
        DynamicObject* GetDynObject(uint32 spellId);
        void AddDynObject(DynamicObject* dynObj);
        void RemoveDynObject(uint32 spellid);
        void RemoveDynObjectWithGUID(ObjectGuid guid) { m_dynObjGUIDs.remove(guid); }
        void RemoveAllDynObjects();

        GameObject* GetGameObject(uint32 spellId) const;
        void AddGameObject(GameObject* gameObj);
        void AddWildGameObject(GameObject* gameObj);
        void RemoveGameObject(GameObject* gameObj, bool del);
        void RemoveGameObject(uint32 spellid, bool del);
        void RemoveAllGameObjects();

        uint32 CalculateDamage(WeaponAttackType attType, bool normalized);
        float GetAPMultiplier(WeaponAttackType attType, bool normalized);
        void ModifyAuraState(AuraState flag, bool apply);
        bool HasAuraState(AuraState flag) const { return HasFlag(UNIT_FIELD_AURASTATE, 1 << (flag - 1)); }
        void UnsummonAllTotems();
        Unit* SelectMagnetTarget(Unit* victim, Spell* spell = NULL, SpellEffectIndex eff = EFFECT_INDEX_0);

        int32 SpellBonusWithCoeffs(Unit* pCaster, SpellEntry const* spellProto, int32 total, int32 benefit, int32 ap_benefit, DamageEffectType damagetype, bool donePart);
        int32 SpellBaseDamageBonusDone(SpellSchoolMask schoolMask);
        int32 SpellBaseDamageBonusTaken(SpellSchoolMask schoolMask);
        uint32 SpellDamageBonusDone(Unit* pVictim, SpellEntry const* spellProto, uint32 pdamage, DamageEffectType damagetype, uint32 stack = 1);
        uint32 SpellDamageBonusTaken(Unit* pCaster, SpellEntry const* spellProto, uint32 pdamage, DamageEffectType damagetype, uint32 stack = 1);
        int32 SpellBaseHealingBonusDone(SpellSchoolMask schoolMask);
        int32 SpellBaseHealingBonusTaken(SpellSchoolMask schoolMask);
        uint32 SpellHealingBonusDone(Unit* pVictim, SpellEntry const* spellProto, int32 healamount, DamageEffectType damagetype, uint32 stack = 1);
        uint32 SpellHealingBonusTaken(Unit* pCaster, SpellEntry const* spellProto, int32 healamount, DamageEffectType damagetype, uint32 stack = 1);
        uint32 MeleeDamageBonusDone(Unit* pVictim, uint32 damage, WeaponAttackType attType, SpellEntry const* spellProto = NULL, DamageEffectType damagetype = DIRECT_DAMAGE, uint32 stack = 1);
        uint32 MeleeDamageBonusTaken(Unit* pCaster, uint32 pdamage, WeaponAttackType attType, SpellEntry const* spellProto = NULL, DamageEffectType damagetype = DIRECT_DAMAGE, uint32 stack = 1);

        bool   IsSpellBlocked(Unit* pCaster, SpellEntry const* spellProto, WeaponAttackType attackType = BASE_ATTACK);
        bool   IsSpellCrit(Unit* pVictim, SpellEntry const* spellProto, SpellSchoolMask schoolMask, WeaponAttackType attackType = BASE_ATTACK);
        uint32 SpellCriticalDamageBonus(SpellEntry const* spellProto, uint32 damage, Unit* pVictim);
        uint32 SpellCriticalHealingBonus(SpellEntry const* spellProto, uint32 damage, Unit* pVictim);

        bool IsTriggeredAtSpellProcEvent(Unit* pVictim, SpellAuraHolder* holder, SpellEntry const* procSpell, uint32 procFlag, uint32 procExtra, WeaponAttackType attType, bool isVictim, SpellProcEventEntry const*& spellProcEvent);
        // Aura proc handlers
        SpellAuraProcResult HandleDummyAuraProc(Unit* pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const* procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown);
        SpellAuraProcResult HandleHasteAuraProc(Unit* pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const* procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown);
        SpellAuraProcResult HandleProcTriggerSpellAuraProc(Unit* pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const* procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown);
        SpellAuraProcResult HandleProcTriggerDamageAuraProc(Unit* pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const* procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown);
        SpellAuraProcResult HandleOverrideClassScriptAuraProc(Unit* pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const* procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown);
        SpellAuraProcResult HandleModCastingSpeedNotStackAuraProc(Unit* pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const* procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown);
        SpellAuraProcResult HandleReflectSpellsSchoolAuraProc(Unit* pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const* procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown);
        SpellAuraProcResult HandleModPowerCostSchoolAuraProc(Unit* pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const* procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown);
        SpellAuraProcResult HandleMechanicImmuneResistanceAuraProc(Unit* pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const* procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown);
        SpellAuraProcResult HandleModResistanceAuraProc(Unit* pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const* procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown);
        SpellAuraProcResult HandleRemoveByDamageChanceProc(Unit* pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const* procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown);
        SpellAuraProcResult HandleInvisibilityAuraProc(Unit* pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const* procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown);
        SpellAuraProcResult HandleNULLProc(Unit* /*pVictim*/, uint32 /*damage*/, Aura* /*triggeredByAura*/, SpellEntry const* /*procSpell*/, uint32 /*procFlag*/, uint32 /*procEx*/, uint32 /*cooldown*/)
        {
            // no proc handler for this aura type
            return SPELL_AURA_PROC_OK;
        }
        SpellAuraProcResult HandleCantTrigger(Unit* /*pVictim*/, uint32 /*damage*/, Aura* /*triggeredByAura*/, SpellEntry const* /*procSpell*/, uint32 /*procFlag*/, uint32 /*procEx*/, uint32 /*cooldown*/)
        {
            // this aura type can't proc
            return SPELL_AURA_PROC_CANT_TRIGGER;
        }

        void SetLastManaUse()
        {
            m_lastManaUseTimer = 5000;
        }
        bool IsUnderLastManaUseEffect() const { return m_lastManaUseTimer; }

        void SetContestedPvP(Player* attackedPlayer = NULL);

        void ApplySpellImmune(uint32 spellId, uint32 op, uint32 type, bool apply);
        void ApplySpellDispelImmunity(const SpellEntry* spellProto, DispelType type, bool apply);
        virtual bool IsImmuneToSpell(SpellEntry const* spellInfo, bool castOnSelf);
        virtual bool IsImmuneToDamage(SpellSchoolMask meleeSchoolMask);
        virtual bool IsImmuneToSpellEffect(SpellEntry const* spellInfo, SpellEffectIndex index, bool castOnSelf) const;

        uint32 CalcArmorReducedDamage(Unit* pVictim, const uint32 damage);
        void CalculateDamageAbsorbAndResist(Unit* pCaster, SpellSchoolMask schoolMask, DamageEffectType damagetype, const uint32 damage, uint32* absorb, uint32* resist, bool canReflect = false);
        void CalculateAbsorbResistBlock(Unit* pCaster, SpellNonMeleeDamage* damageInfo, SpellEntry const* spellProto, WeaponAttackType attType = BASE_ATTACK);

        virtual void UpdateSpeed(UnitMoveType mtype, bool forced, float ratio = 1.0f);
        float GetSpeed(UnitMoveType mtype) const;
        float GetSpeedRate(UnitMoveType mtype) const { return m_speed_rate[mtype]; }
        void SetSpeedRate(UnitMoveType mtype, float rate, bool forced = false);

        bool IsHover() const { return HasAuraType(SPELL_AURA_HOVER); }

        void _RemoveAllAuraMods();
        void _ApplyAllAuraMods();

        int32 CalculateSpellDamage(Unit const* target, SpellEntry const* spellProto, SpellEffectIndex effect_index, int32 const* basePoints = NULL);

        float CalculateLevelPenalty(SpellEntry const* spellProto) const;

        void AddFollower(FollowerReference* pRef) { m_FollowingRefManager.insertFirst(pRef); }
        void RemoveFollower(FollowerReference* /*pRef*/) { /* nothing to do yet */ }

        MotionMaster* GetMotionMaster() { return &i_motionMaster; }

        bool IsStopped() const { return !(hasUnitState(UNIT_STAT_MOVING)); }
        void StopMoving(bool forceSendStop = false);
        void InterruptMoving(bool forceSendStop = false);

        ///----------Various crowd control methods-----------------
        bool IsImmobilized() const { return hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED); }
        void SetImmobilizedState(bool apply, bool stun = false);

        // These getters operate on unit flags set by IncapacitatedState and are meant for formal usage in conjunction with spell effects only
        // For actual internal movement states use UnitState flags
        // TODO: The UnitState thing needs to be rewriten at some point, this kind of duality is bad
        bool IsFleeing() const { return HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_FLEEING); }
        bool IsConfused() const { return HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_CONFUSED); }
        bool IsStunned() const { return HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED); }
        bool IsIncapacitated() const { return (IsFleeing() || IsConfused() || IsStunned()); }

        void SetFeared(bool apply, ObjectGuid casterGuid = ObjectGuid(), uint32 spellID = 0, uint32 time = 0);
        void SetConfused(bool apply, ObjectGuid casterGuid = ObjectGuid(), uint32 spellID = 0);
        void SetStunned(bool apply);
        void SetIncapacitatedState(bool apply, uint32 state = 0, ObjectGuid casterGuid = ObjectGuid(), uint32 spellID = 0, uint32 time = 0);
        ///----------End of crowd control methods----------
        void SetFeignDeath(bool apply, ObjectGuid casterGuid = ObjectGuid());

        void AddComboPointHolder(uint32 lowguid) { m_ComboPointHolders.insert(lowguid); }
        void RemoveComboPointHolder(uint32 lowguid) { m_ComboPointHolders.erase(lowguid); }
        void ClearComboPointHolders();

        ///----------Pet responses methods-----------------
        void SendPetCastFail(uint32 spellid, SpellCastResult msg);
        void SendPetActionFeedback(uint8 msg);
        void SendPetTalk(uint32 pettalk);
        void SendPetAIReaction();
        ///----------End of Pet responses methods----------

        void PropagateSpeedChange() { GetMotionMaster()->PropagateSpeedChange(); }

        // reactive attacks
        void ClearAllReactives();
        void StartReactiveTimer(ReactiveType reactive) { m_reactiveTimer[reactive] = REACTIVE_TIMER_START;}
        void UpdateReactives(uint32 p_time);

        // group updates
        void UpdateAuraForGroup(uint8 slot);

        // pet auras
        typedef std::set<PetAura const*> PetAuraSet;
        PetAuraSet m_petAuras;
        void AddPetAura(PetAura const* petSpell);
        void RemovePetAura(PetAura const* petSpell);

        // Movement info
        MovementInfo m_movementInfo;
        Movement::MoveSpline* movespline;

        void ScheduleAINotify(uint32 delay);
        bool IsAINotifyScheduled() const { return m_AINotifyScheduled;}
        void _SetAINotifyScheduled(bool on) { m_AINotifyScheduled = on;}       // only for call from RelocationNotifyEvent code
        void OnRelocated();

        bool IsLinkingEventTrigger() { return m_isCreatureLinkingTrigger; }

        virtual bool CanSwim() const = 0;
        virtual bool CanFly() const = 0;

protected:
        struct WeaponDamageInfo
        {
            struct Weapon
            {
                struct Damage
                {
                    SpellSchools school = SPELL_SCHOOL_NORMAL;
                    float value[2] = { BASE_MINDAMAGE, BASE_MAXDAMAGE };
                };

                uint32 lines = 1;
                Damage damage[MAX_ITEM_PROTO_DAMAGES];
            };

            Weapon weapon[MAX_ATTACK];
        };

        explicit Unit();

        void _UpdateSpells(uint32 time);
        void _UpdateAutoRepeatSpell();
        bool m_AutoRepeatFirstCast;

        uint32 m_attackTimer[MAX_ATTACK];

        float m_createStats[MAX_STATS];

        AttackerSet m_attackers;
        Unit* m_attacking;

        DeathState m_deathState; ///< The current state of life/death for this \ref Unit

        SpellAuraHolderMap m_spellAuraHolders;
        SpellAuraHolderMap::iterator m_spellAuraHoldersUpdateIterator; // != end() in Unit::m_spellAuraHolders update and point to next element
        AuraList m_deletedAuras;                            // auras removed while in ApplyModifier and waiting deleted
        SpellAuraHolderList m_deletedHolders;

        // Store Auras for which the target must be tracked
        TrackedAuraTargetMap m_trackedAuraTargets[MAX_TRACKED_AURA_TYPES];

        GuidList m_dynObjGUIDs;

        typedef std::list<GameObject*> GameObjectList;
        GameObjectList m_gameObj;
        typedef std::map<uint32, ObjectGuid> WildGameObjectMap;
        WildGameObjectMap m_wildGameObjs;
        bool m_isSorted;
        uint32 m_transform;

        AuraList m_modAuras[TOTAL_AURAS];
        float m_auraModifiersGroup[UNIT_MOD_END][MODIFIER_TYPE_END];
        float m_weaponDamage[MAX_ATTACK][2];
        WeaponDamageInfo m_weaponDamageInfo;

        bool m_canModifyStats;
        // std::list< spellEffectPair > AuraSpells[TOTAL_AURAS];  // TODO: use this if ok for mem

        float m_speed_rate[MAX_MOVE_TYPE];

        CharmInfo* m_charmInfo;

        virtual SpellSchoolMask GetMeleeDamageSchoolMask() const;

        MotionMaster i_motionMaster;

        uint32 m_reactiveTimer[MAX_REACTIVE];
        uint32 m_regenTimer;
        uint32 m_lastManaUseTimer;

        void DisableSpline();
        bool m_isCreatureLinkingTrigger;
        bool m_isSpawningLinked;

    private:

    void CleanupDeletedAuras();
        void UpdateSplineMovement(uint32 t_diff);

        Unit* _GetTotem(TotemSlot slot) const;              // for templated function without include need
        Pet* _GetPet(ObjectGuid guid) const;                // for templated function without include need

        // Wrapper called by DealDamage when a creature is killed
        void JustKilledCreature(Creature* victim, Player* responsiblePlayer);

        uint32 m_state;                                     // Even derived shouldn't modify
        uint32 m_CombatTimer;
        bool   m_dummyCombatState;                          // Used to keep combat state during some aura

        Spell* m_currentSpells[CURRENT_MAX_SPELL];
        uint32 m_castCounter;                               // count casts chain of triggered spells for prevent infinity cast crashes

        UnitVisibility m_Visibility;
        Position m_last_notified_position;
        bool m_AINotifyScheduled;
        ShortTimeTracker m_movesplineTimer;

        Diminishing m_Diminishing;
        // Manage all Units threatening us
        ThreatManager m_ThreatManager;
        // Manage all Units that are threatened by us
        HostileRefManager m_HostileRefManager;

        FollowerRefManager m_FollowingRefManager;

        ComboPointHolderSet m_ComboPointHolders;

        GuidSet m_guardianPets;

        ObjectGuid m_TotemSlot[MAX_TOTEM_SLOT];

        ObjectGuid m_fixateTargetGuid;                      //< Stores the Guid of a fixated target

    private:                                                // Error traps for some wrong args using
        // this will catch and prevent build for any cases when all optional args skipped and instead triggered used non boolean type
        // no bodies expected for this declarations
        template <typename TR>
        void CastSpell(Unit* Victim, uint32 spell, TR triggered);
        template <typename TR>
        void CastSpell(Unit* Victim, SpellEntry const* spell, TR triggered);
        template <typename TR>
        void CastCustomSpell(Unit* Victim, uint32 spell, int32 const* bp0, int32 const* bp1, int32 const* bp2, TR triggered);
        template <typename SP, typename TR>
        void CastCustomSpell(Unit* Victim, SpellEntry const* spell, int32 const* bp0, int32 const* bp1, int32 const* bp2, TR triggered);
        template <typename TR>
        void CastSpell(float x, float y, float z, uint32 spell, TR triggered);
        template <typename TR>
        void CastSpell(float x, float y, float z, SpellEntry const* spell, TR triggered);
};

template<typename Func>
void Unit::CallForAllControlledUnits(Func const& func, uint32 controlledMask)
{
    if (controlledMask & CONTROLLED_PET)
        if (Pet* pet = GetPet())
        {
            func(pet);
        }

    if (controlledMask & CONTROLLED_MINIPET)
        if (Pet* mini = GetMiniPet())
        {
            func(mini);
        }

    if (controlledMask & CONTROLLED_GUARDIANS)
    {
        for (GuidSet::const_iterator itr = m_guardianPets.begin(); itr != m_guardianPets.end();)
            if (Pet* guardian = _GetPet(*(itr++)))
            {
                func(guardian);
            }
    }

    if (controlledMask & CONTROLLED_TOTEMS)
    {
        for (int i = 0; i < MAX_TOTEM_SLOT; ++i)
            if (Unit* totem = _GetTotem(TotemSlot(i)))
            {
                func(totem);
            }
    }

    if (controlledMask & CONTROLLED_CHARM)
        if (Unit* charm = GetCharm())
        {
            func(charm);
        }
}


template<typename Func>
bool Unit::CheckAllControlledUnits(Func const& func, uint32 controlledMask) const
{
    if (controlledMask & CONTROLLED_PET)
        if (Pet const* pet = GetPet())
            if (func(pet))
            {
                return true;
            }

    if (controlledMask & CONTROLLED_MINIPET)
        if (Pet* mini = GetMiniPet())
            if (func(mini))
            {
                return true;
            }

    if (controlledMask & CONTROLLED_GUARDIANS)
    {
        for (GuidSet::const_iterator itr = m_guardianPets.begin(); itr != m_guardianPets.end();)
            if (Pet const* guardian = _GetPet(*(itr++)))
                if (func(guardian))
                {
                    return true;
                }
    }

    if (controlledMask & CONTROLLED_TOTEMS)
    {
        for (int i = 0; i < MAX_TOTEM_SLOT; ++i)
            if (Unit const* totem = _GetTotem(TotemSlot(i)))
                if (func(totem))
                {
                    return true;
                }
    }

    if (controlledMask & CONTROLLED_CHARM)
        if (Unit const* charm = GetCharm())
            if (func(charm))
            {
                return true;
            }

    return false;
}

/** @} */

#endif
